Auto merge of #139 - ollie27:bigint_hash, r=cuviper
bigint: simplify Hash There cannot be any leading zeros in a BigUint so just derive Hash which will just hash the Vec directly. Add Hash to Sign so we can derive it for BigInt as well.
This commit is contained in:
commit
9b45e6dd9b
|
@ -66,7 +66,7 @@ use std::iter::repeat;
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub};
|
use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub};
|
||||||
use std::str::{self, FromStr};
|
use std::str::{self, FromStr};
|
||||||
use std::{fmt, hash};
|
use std::fmt;
|
||||||
use std::cmp::Ordering::{self, Less, Greater, Equal};
|
use std::cmp::Ordering::{self, Less, Greater, Equal};
|
||||||
use std::{u8, i64, u64};
|
use std::{u8, i64, u64};
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ fn div_wide(hi: BigDigit, lo: BigDigit, divisor: BigDigit) -> (BigDigit, BigDigi
|
||||||
///
|
///
|
||||||
/// A `BigUint`-typed value `BigUint { data: vec!(a, b, c) }` represents a number
|
/// A `BigUint`-typed value `BigUint { data: vec!(a, b, c) }` represents a number
|
||||||
/// `(a + b * big_digit::BASE + c * big_digit::BASE^2)`.
|
/// `(a + b * big_digit::BASE + c * big_digit::BASE^2)`.
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash)]
|
||||||
pub struct BigUint {
|
pub struct BigUint {
|
||||||
data: Vec<BigDigit>
|
data: Vec<BigDigit>
|
||||||
}
|
}
|
||||||
|
@ -222,22 +222,6 @@ impl Default for BigUint {
|
||||||
fn default() -> BigUint { Zero::zero() }
|
fn default() -> BigUint { Zero::zero() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl hash::Hash for BigUint {
|
|
||||||
fn hash<H>(&self, state: &mut H) where H: hash::Hasher {
|
|
||||||
// hash 0 in case it's all 0's
|
|
||||||
0u32.hash(state);
|
|
||||||
|
|
||||||
let mut found_first_value = false;
|
|
||||||
for elem in self.data.iter().rev() {
|
|
||||||
// don't hash any leading 0's, they shouldn't affect the hash
|
|
||||||
if found_first_value || *elem != 0 {
|
|
||||||
found_first_value = true;
|
|
||||||
elem.hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for BigUint {
|
impl fmt::Display for BigUint {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self.to_str_radix(10))
|
write!(f, "{}", self.to_str_radix(10))
|
||||||
|
@ -1650,7 +1634,7 @@ fn get_radix_base(radix: u32) -> (DoubleBigDigit, usize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Sign is a `BigInt`'s composing element.
|
/// A Sign is a `BigInt`'s composing element.
|
||||||
#[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
|
#[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone, Debug, RustcEncodable, RustcDecodable, Hash)]
|
||||||
pub enum Sign { Minus, NoSign, Plus }
|
pub enum Sign { Minus, NoSign, Plus }
|
||||||
|
|
||||||
impl Neg for Sign {
|
impl Neg for Sign {
|
||||||
|
@ -1681,7 +1665,7 @@ impl Mul<Sign> for Sign {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A big signed integer type.
|
/// A big signed integer type.
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash)]
|
||||||
pub struct BigInt {
|
pub struct BigInt {
|
||||||
sign: Sign,
|
sign: Sign,
|
||||||
data: BigUint
|
data: BigUint
|
||||||
|
@ -1728,13 +1712,6 @@ impl fmt::Display for BigInt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl hash::Hash for BigInt {
|
|
||||||
fn hash<H>(&self, state: &mut H) where H: hash::Hasher {
|
|
||||||
(self.sign == Plus).hash(state);
|
|
||||||
self.data.hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for BigInt {
|
impl FromStr for BigInt {
|
||||||
type Err = ParseBigIntError;
|
type Err = ParseBigIntError;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue