From 36d698d544953c7fc03a8bf10ea9423e47732ab8 Mon Sep 17 00:00:00 2001 From: gifnksm Date: Sun, 25 Aug 2013 22:18:24 +0900 Subject: [PATCH 1/6] bigint: cfg(target_arch = ...) => cfg(target_word_size = ...) --- src/libextra/num/bigint.rs | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index c86c4dd07ed..e2fc3e6bd8a 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -32,9 +32,7 @@ A BigDigit is a BigUint's composing element. A BigDigit is half the size of machine word size. */ -#[cfg(target_arch = "x86")] -#[cfg(target_arch = "arm")] -#[cfg(target_arch = "mips")] +#[cfg(target_word_size = "32")] pub type BigDigit = u16; /** @@ -42,7 +40,7 @@ A BigDigit is a BigUint's composing element. A BigDigit is half the size of machine word size. */ -#[cfg(target_arch = "x86_64")] +#[cfg(target_word_size = "64")] pub type BigDigit = u32; pub static ZERO_BIG_DIGIT: BigDigit = 0; @@ -50,12 +48,10 @@ pub static ZERO_BIG_DIGIT: BigDigit = 0; pub mod BigDigit { use bigint::BigDigit; - #[cfg(target_arch = "x86")] - #[cfg(target_arch = "arm")] - #[cfg(target_arch = "mips")] + #[cfg(target_word_size = "32")] pub static bits: uint = 16; - #[cfg(target_arch = "x86_64")] + #[cfg(target_word_size = "64")] pub static bits: uint = 32; pub static base: uint = 1 << bits; @@ -659,8 +655,7 @@ impl BigUint { } } -#[cfg(target_arch = "x86_64")] - +#[cfg(target_word_size = "64")] fn get_radix_base(radix: uint) -> (uint, uint) { assert!(1 < radix && radix <= 16); match radix { @@ -683,10 +678,7 @@ fn get_radix_base(radix: uint) -> (uint, uint) { } } -#[cfg(target_arch = "arm")] -#[cfg(target_arch = "x86")] -#[cfg(target_arch = "mips")] - +#[cfg(target_word_size = "32")] fn get_radix_base(radix: uint) -> (uint, uint) { assert!(1 < radix && radix <= 16); match radix { @@ -1233,7 +1225,7 @@ mod biguint_tests { test_shl_bits(); - #[cfg(target_arch = "x86_64")] + #[cfg(target_word_size = "64")] fn test_shl_bits() { check(~[0x7654_3210, 0xfedc_ba98, 0x7654_3210, 0xfedc_ba98], 4, @@ -1245,9 +1237,7 @@ mod biguint_tests { 0x5555_4444, 0x7777_6666, 0x8888]); } - #[cfg(target_arch = "arm")] - #[cfg(target_arch = "x86")] - #[cfg(target_arch = "mips")] + #[cfg(target_word_size = "32")] fn test_shl_bits() { check(~[0x3210, 0x7654, 0xba98, 0xfedc, 0x3210, 0x7654, 0xba98, 0xfedc], 4, @@ -1262,9 +1252,7 @@ mod biguint_tests { } #[test] - #[ignore(cfg(target_arch = "x86"))] - #[ignore(cfg(target_arch = "arm"))] - #[ignore(cfg(target_arch = "mips"))] + #[ignore(cfg(target_word_size = "32"))] fn test_shr() { fn check(v: ~[BigDigit], shift: uint, ans: ~[BigDigit]) { assert_eq!(BigUint::new(v) >> shift, BigUint::new(ans)); @@ -1279,7 +1267,7 @@ mod biguint_tests { check(~[0, 1], 1, ~[0x80000000]); test_shr_bits(); - #[cfg(target_arch = "x86_64")] + #[cfg(target_word_size = "64")] fn test_shr_bits() { check(~[0x6543_2100, 0xedcb_a987, 0x6543_210f, 0xedcb_a987, 0xf], 4, @@ -1291,9 +1279,7 @@ mod biguint_tests { 0x6666_5555, 0x8888_7777]); } - #[cfg(target_arch = "arm")] - #[cfg(target_arch = "x86")] - #[cfg(target_arch = "mips")] + #[cfg(target_word_size = "32")] fn test_shr_bits() { check(~[0x2100, 0x6543, 0xa987, 0xedcb, 0x210f, 0x6543, 0xa987, 0xedcb, 0xf], 4, From b247d176297f85c01e89c64d6058dbdd539cb95a Mon Sep 17 00:00:00 2001 From: gifnksm Date: Sun, 25 Aug 2013 22:36:55 +0900 Subject: [PATCH 2/6] bigint: remove unnecessary method implements --- src/libextra/num/bigint.rs | 42 -------------------------------------- 1 file changed, 42 deletions(-) diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index e2fc3e6bd8a..f15f4db2ebd 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -88,14 +88,10 @@ pub struct BigUint { } impl Eq for BigUint { - fn eq(&self, other: &BigUint) -> bool { self.equals(other) } - - fn ne(&self, other: &BigUint) -> bool { !self.equals(other) } } impl TotalEq for BigUint { - fn equals(&self, other: &BigUint) -> bool { match self.cmp(other) { Equal => true, _ => false } } @@ -106,18 +102,6 @@ impl Ord for BigUint { fn lt(&self, other: &BigUint) -> bool { match self.cmp(other) { Less => true, _ => false} } - - fn le(&self, other: &BigUint) -> bool { - match self.cmp(other) { Less | Equal => true, _ => false } - } - - fn ge(&self, other: &BigUint) -> bool { - match self.cmp(other) { Greater | Equal => true, _ => false } - } - - fn gt(&self, other: &BigUint) -> bool { - match self.cmp(other) { Greater => true, _ => false } - } } impl TotalOrd for BigUint { @@ -710,18 +694,6 @@ impl Ord for Sign { fn lt(&self, other: &Sign) -> bool { match self.cmp(other) { Less => true, _ => false} } - - fn le(&self, other: &Sign) -> bool { - match self.cmp(other) { Less | Equal => true, _ => false } - } - - fn ge(&self, other: &Sign) -> bool { - match self.cmp(other) { Greater | Equal => true, _ => false } - } - - fn gt(&self, other: &Sign) -> bool { - match self.cmp(other) { Greater => true, _ => false } - } } impl TotalEq for Sign { @@ -762,8 +734,6 @@ pub struct BigInt { impl Eq for BigInt { fn eq(&self, other: &BigInt) -> bool { self.equals(other) } - - fn ne(&self, other: &BigInt) -> bool { !self.equals(other) } } impl TotalEq for BigInt { @@ -778,18 +748,6 @@ impl Ord for BigInt { fn lt(&self, other: &BigInt) -> bool { match self.cmp(other) { Less => true, _ => false} } - - fn le(&self, other: &BigInt) -> bool { - match self.cmp(other) { Less | Equal => true, _ => false } - } - - fn ge(&self, other: &BigInt) -> bool { - match self.cmp(other) { Greater | Equal => true, _ => false } - } - - fn gt(&self, other: &BigInt) -> bool { - match self.cmp(other) { Greater => true, _ => false } - } } impl TotalOrd for BigInt { From 17c8f8bd0cc1bd58f6adbf0ca954ec326f8ef8c6 Mon Sep 17 00:00:00 2001 From: gifnksm Date: Sun, 25 Aug 2013 22:47:24 +0900 Subject: [PATCH 3/6] bigint: inlining small functions --- src/libextra/num/bigint.rs | 189 ++++++++++++++++++------------------- 1 file changed, 92 insertions(+), 97 deletions(-) diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index f15f4db2ebd..00eec3e9ac4 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -58,19 +58,19 @@ pub mod BigDigit { static hi_mask: uint = (-1 as uint) << bits; static lo_mask: uint = (-1 as uint) >> bits; - + #[inline] fn get_hi(n: uint) -> BigDigit { (n >> bits) as BigDigit } - + #[inline] fn get_lo(n: uint) -> BigDigit { (n & lo_mask) as BigDigit } /// Split one machine sized unsigned integer into two BigDigits. - + #[inline] pub fn from_uint(n: uint) -> (BigDigit, BigDigit) { (get_hi(n), get_lo(n)) } /// Join two BigDigits into one machine sized unsigned integer - + #[inline] pub fn to_uint(hi: BigDigit, lo: BigDigit) -> uint { (lo as uint) | ((hi as uint) << bits) } @@ -88,24 +88,26 @@ pub struct BigUint { } impl Eq for BigUint { + #[inline] fn eq(&self, other: &BigUint) -> bool { self.equals(other) } } impl TotalEq for BigUint { + #[inline] fn equals(&self, other: &BigUint) -> bool { match self.cmp(other) { Equal => true, _ => false } } } impl Ord for BigUint { - + #[inline] fn lt(&self, other: &BigUint) -> bool { match self.cmp(other) { Less => true, _ => false} } } impl TotalOrd for BigUint { - + #[inline] fn cmp(&self, other: &BigUint) -> Ordering { let (s_len, o_len) = (self.data.len(), other.data.len()); if s_len < o_len { return Less; } @@ -120,12 +122,12 @@ impl TotalOrd for BigUint { } impl ToStr for BigUint { - + #[inline] fn to_str(&self) -> ~str { self.to_str_radix(10) } } impl FromStr for BigUint { - + #[inline] fn from_str(s: &str) -> Option { FromStrRadix::from_str_radix(s, 10) } @@ -134,17 +136,17 @@ impl FromStr for BigUint { impl Num for BigUint {} impl Orderable for BigUint { - + #[inline] fn min(&self, other: &BigUint) -> BigUint { if self < other { self.clone() } else { other.clone() } } - + #[inline] fn max(&self, other: &BigUint) -> BigUint { if self > other { self.clone() } else { other.clone() } } - + #[inline] fn clamp(&self, mn: &BigUint, mx: &BigUint) -> BigUint { if self > mx { mx.clone() } else if self < mn { mn.clone() } else { self.clone() } @@ -152,7 +154,7 @@ impl Orderable for BigUint { } impl Shl for BigUint { - + #[inline] fn shl(&self, rhs: &uint) -> BigUint { let n_unit = *rhs / BigDigit::bits; let n_bits = *rhs % BigDigit::bits; @@ -161,7 +163,7 @@ impl Shl for BigUint { } impl Shr for BigUint { - + #[inline] fn shr(&self, rhs: &uint) -> BigUint { let n_unit = *rhs / BigDigit::bits; let n_bits = *rhs % BigDigit::bits; @@ -170,22 +172,21 @@ impl Shr for BigUint { } impl Zero for BigUint { - + #[inline] fn zero() -> BigUint { BigUint::new(~[]) } - + #[inline] fn is_zero(&self) -> bool { self.data.is_empty() } } impl One for BigUint { - + #[inline] fn one() -> BigUint { BigUint::new(~[1]) } } impl Unsigned for BigUint {} impl Add for BigUint { - fn add(&self, other: &BigUint) -> BigUint { let new_len = num::max(self.data.len(), other.data.len()); @@ -205,7 +206,6 @@ impl Add for BigUint { } impl Sub for BigUint { - fn sub(&self, other: &BigUint) -> BigUint { let new_len = num::max(self.data.len(), other.data.len()); @@ -278,14 +278,14 @@ impl Mul for BigUint { return BigUint::new(prod); } - + #[inline] fn cut_at(a: &BigUint, n: uint) -> (BigUint, BigUint) { let mid = num::min(a.data.len(), n); return (BigUint::from_slice(a.data.slice(mid, a.data.len())), BigUint::from_slice(a.data.slice(0, mid))); } - + #[inline] fn sub_sign(a: BigUint, b: BigUint) -> (Ordering, BigUint) { match a.cmp(&b) { Less => (Less, b - a), @@ -297,7 +297,7 @@ impl Mul for BigUint { } impl Div for BigUint { - + #[inline] fn div(&self, other: &BigUint) -> BigUint { let (q, _) = self.div_rem(other); return q; @@ -305,7 +305,7 @@ impl Div for BigUint { } impl Rem for BigUint { - + #[inline] fn rem(&self, other: &BigUint) -> BigUint { let (_, r) = self.div_rem(other); return r; @@ -313,29 +313,28 @@ impl Rem for BigUint { } impl Neg for BigUint { - + #[inline] fn neg(&self) -> BigUint { fail!() } } impl Integer for BigUint { - + #[inline] fn div_rem(&self, other: &BigUint) -> (BigUint, BigUint) { self.div_mod_floor(other) } - + #[inline] fn div_floor(&self, other: &BigUint) -> BigUint { let (d, _) = self.div_mod_floor(other); return d; } - + #[inline] fn mod_floor(&self, other: &BigUint) -> BigUint { let (_, m) = self.div_mod_floor(other); return m; } - fn div_mod_floor(&self, other: &BigUint) -> (BigUint, BigUint) { if other.is_zero() { fail!() } if self.is_zero() { return (Zero::zero(), Zero::zero()); } @@ -423,7 +422,7 @@ impl Integer for BigUint { * * The result is always positive */ - + #[inline] fn gcd(&self, other: &BigUint) -> BigUint { // Use Euclid's algorithm let mut m = (*self).clone(); @@ -439,15 +438,15 @@ impl Integer for BigUint { /** * Calculates the Lowest Common Multiple (LCM) of the number and `other` */ - + #[inline] fn lcm(&self, other: &BigUint) -> BigUint { ((*self * *other) / self.gcd(other)) } /// Returns `true` if the number can be divided by `other` without leaving a remainder - + #[inline] fn is_multiple_of(&self, other: &BigUint) -> bool { (*self % *other).is_zero() } /// Returns `true` if the number is divisible by `2` - + #[inline] fn is_even(&self) -> bool { // Considering only the last digit. if self.data.is_empty() { @@ -458,24 +457,23 @@ impl Integer for BigUint { } /// Returns `true` if the number is not divisible by `2` - + #[inline] fn is_odd(&self) -> bool { !self.is_even() } } impl IntConvertible for BigUint { - + #[inline] fn to_int(&self) -> int { num::min(self.to_uint(), int::max_value as uint) as int } - + #[inline] fn from_int(n: int) -> BigUint { if (n < 0) { Zero::zero() } else { BigUint::from_uint(n as uint) } } } impl ToStrRadix for BigUint { - fn to_str_radix(&self, radix: uint) -> ~str { assert!(1 < radix && radix <= 16); let (base, max_len) = get_radix_base(radix); @@ -484,7 +482,6 @@ impl ToStrRadix for BigUint { } return fill_concat(convert_base((*self).clone(), base), radix, max_len); - fn convert_base(n: BigUint, base: uint) -> ~[BigDigit] { let divider = BigUint::from_uint(base); let mut result = ~[]; @@ -500,7 +497,6 @@ impl ToStrRadix for BigUint { return result; } - fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> ~str { if v.is_empty() { return ~"0" } let mut s = str::with_capacity(v.len() * l); @@ -516,7 +512,7 @@ impl ToStrRadix for BigUint { impl FromStrRadix for BigUint { /// Creates and initializes an BigUint. - + #[inline] fn from_str_radix(s: &str, radix: uint) -> Option { BigUint::parse_bytes(s.as_bytes(), radix) @@ -525,7 +521,7 @@ impl FromStrRadix for BigUint { impl BigUint { /// Creates and initializes an BigUint. - + #[inline] pub fn new(v: ~[BigDigit]) -> BigUint { // omit trailing zeros let new_len = v.rposition(|n| *n != 0).map_move_default(0, |p| p + 1); @@ -537,7 +533,7 @@ impl BigUint { } /// Creates and initializes an BigUint. - + #[inline] pub fn from_uint(n: uint) -> BigUint { match BigDigit::from_uint(n) { (0, 0) => Zero::zero(), @@ -547,13 +543,12 @@ impl BigUint { } /// Creates and initializes an BigUint. - + #[inline] pub fn from_slice(slice: &[BigDigit]) -> BigUint { return BigUint::new(slice.to_owned()); } /// Creates and initializes an BigUint. - pub fn parse_bytes(buf: &[u8], radix: uint) -> Option { let (base, unit_len) = get_radix_base(radix); @@ -583,6 +578,7 @@ impl BigUint { /// Converts this big integer into a uint, returning the uint::max_value if /// it's too large to fit in a uint. + #[inline] pub fn to_uint(&self) -> uint { match self.data.len() { 0 => 0, @@ -592,7 +588,7 @@ impl BigUint { } } - + #[inline] fn shl_unit(&self, n_unit: uint) -> BigUint { if n_unit == 0 || self.is_zero() { return (*self).clone(); } @@ -600,7 +596,7 @@ impl BigUint { + self.data); } - + #[inline] fn shl_bits(&self, n_bits: uint) -> BigUint { if n_bits == 0 || self.is_zero() { return (*self).clone(); } @@ -616,7 +612,7 @@ impl BigUint { return BigUint::new(shifted); } - + #[inline] fn shr_unit(&self, n_unit: uint) -> BigUint { if n_unit == 0 { return (*self).clone(); } if self.data.len() < n_unit { return Zero::zero(); } @@ -625,7 +621,7 @@ impl BigUint { ); } - + #[inline] fn shr_bits(&self, n_bits: uint) -> BigUint { if n_bits == 0 || self.data.is_empty() { return (*self).clone(); } @@ -640,6 +636,7 @@ impl BigUint { } #[cfg(target_word_size = "64")] +#[inline] fn get_radix_base(radix: uint) -> (uint, uint) { assert!(1 < radix && radix <= 16); match radix { @@ -663,6 +660,7 @@ fn get_radix_base(radix: uint) -> (uint, uint) { } #[cfg(target_word_size = "32")] +#[inline] fn get_radix_base(radix: uint) -> (uint, uint) { assert!(1 < radix && radix <= 16); match radix { @@ -690,19 +688,18 @@ fn get_radix_base(radix: uint) -> (uint, uint) { pub enum Sign { Minus, Zero, Plus } impl Ord for Sign { - + #[inline] fn lt(&self, other: &Sign) -> bool { match self.cmp(other) { Less => true, _ => false} } } impl TotalEq for Sign { - fn equals(&self, other: &Sign) -> bool { - *self == *other - } + #[inline] + fn equals(&self, other: &Sign) -> bool { *self == *other } } impl TotalOrd for Sign { - + #[inline] fn cmp(&self, other: &Sign) -> Ordering { match (*self, *other) { (Minus, Minus) | (Zero, Zero) | (Plus, Plus) => Equal, @@ -714,7 +711,7 @@ impl TotalOrd for Sign { impl Neg for Sign { /// Negate Sign value. - + #[inline] fn neg(&self) -> Sign { match *self { Minus => Plus, @@ -732,26 +729,26 @@ pub struct BigInt { } impl Eq for BigInt { - + #[inline] fn eq(&self, other: &BigInt) -> bool { self.equals(other) } } impl TotalEq for BigInt { - + #[inline] fn equals(&self, other: &BigInt) -> bool { match self.cmp(other) { Equal => true, _ => false } } } impl Ord for BigInt { - + #[inline] fn lt(&self, other: &BigInt) -> bool { match self.cmp(other) { Less => true, _ => false} } } impl TotalOrd for BigInt { - + #[inline] fn cmp(&self, other: &BigInt) -> Ordering { let scmp = self.sign.cmp(&other.sign); if scmp != Equal { return scmp; } @@ -765,12 +762,12 @@ impl TotalOrd for BigInt { } impl ToStr for BigInt { - + #[inline] fn to_str(&self) -> ~str { self.to_str_radix(10) } } impl FromStr for BigInt { - + #[inline] fn from_str(s: &str) -> Option { FromStrRadix::from_str_radix(s, 10) } @@ -779,17 +776,17 @@ impl FromStr for BigInt { impl Num for BigInt {} impl Orderable for BigInt { - + #[inline] fn min(&self, other: &BigInt) -> BigInt { if self < other { self.clone() } else { other.clone() } } - + #[inline] fn max(&self, other: &BigInt) -> BigInt { if self > other { self.clone() } else { other.clone() } } - + #[inline] fn clamp(&self, mn: &BigInt, mx: &BigInt) -> BigInt { if self > mx { mx.clone() } else if self < mn { mn.clone() } else { self.clone() } @@ -797,38 +794,38 @@ impl Orderable for BigInt { } impl Shl for BigInt { - + #[inline] fn shl(&self, rhs: &uint) -> BigInt { BigInt::from_biguint(self.sign, self.data << *rhs) } } impl Shr for BigInt { - + #[inline] fn shr(&self, rhs: &uint) -> BigInt { BigInt::from_biguint(self.sign, self.data >> *rhs) } } impl Zero for BigInt { - + #[inline] fn zero() -> BigInt { BigInt::from_biguint(Zero, Zero::zero()) } - + #[inline] fn is_zero(&self) -> bool { self.sign == Zero } } impl One for BigInt { - + #[inline] fn one() -> BigInt { BigInt::from_biguint(Plus, One::one()) } } impl Signed for BigInt { - + #[inline] fn abs(&self) -> BigInt { match self.sign { Plus | Zero => self.clone(), @@ -836,12 +833,12 @@ impl Signed for BigInt { } } - + #[inline] fn abs_sub(&self, other: &BigInt) -> BigInt { if *self <= *other { Zero::zero() } else { *self - *other } } - + #[inline] fn signum(&self) -> BigInt { match self.sign { Plus => BigInt::from_biguint(Plus, One::one()), @@ -850,15 +847,15 @@ impl Signed for BigInt { } } - + #[inline] fn is_positive(&self) -> bool { self.sign == Plus } - + #[inline] fn is_negative(&self) -> bool { self.sign == Minus } } impl Add for BigInt { - + #[inline] fn add(&self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { (Zero, _) => other.clone(), @@ -873,7 +870,7 @@ impl Add for BigInt { } impl Sub for BigInt { - + #[inline] fn sub(&self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { (Zero, _) => -other, @@ -891,7 +888,7 @@ impl Sub for BigInt { } impl Mul for BigInt { - + #[inline] fn mul(&self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { (Zero, _) | (_, Zero) => Zero::zero(), @@ -906,7 +903,7 @@ impl Mul for BigInt { } impl Div for BigInt { - + #[inline] fn div(&self, other: &BigInt) -> BigInt { let (q, _) = self.div_rem(other); return q; @@ -914,7 +911,7 @@ impl Div for BigInt { } impl Rem for BigInt { - + #[inline] fn rem(&self, other: &BigInt) -> BigInt { let (_, r) = self.div_rem(other); return r; @@ -922,14 +919,14 @@ impl Rem for BigInt { } impl Neg for BigInt { - + #[inline] fn neg(&self) -> BigInt { BigInt::from_biguint(self.sign.neg(), self.data.clone()) } } impl Integer for BigInt { - + #[inline] fn div_rem(&self, other: &BigInt) -> (BigInt, BigInt) { // r.sign == self.sign let (d_ui, r_ui) = self.data.div_mod_floor(&other.data); @@ -944,19 +941,18 @@ impl Integer for BigInt { } } - + #[inline] fn div_floor(&self, other: &BigInt) -> BigInt { let (d, _) = self.div_mod_floor(other); return d; } - + #[inline] fn mod_floor(&self, other: &BigInt) -> BigInt { let (_, m) = self.div_mod_floor(other); return m; } - fn div_mod_floor(&self, other: &BigInt) -> (BigInt, BigInt) { // m.sign == other.sign let (d_ui, m_ui) = self.data.div_rem(&other.data); @@ -984,7 +980,7 @@ impl Integer for BigInt { * * The result is always positive */ - + #[inline] fn gcd(&self, other: &BigInt) -> BigInt { BigInt::from_biguint(Plus, self.data.gcd(&other.data)) } @@ -992,26 +988,26 @@ impl Integer for BigInt { /** * Calculates the Lowest Common Multiple (LCM) of the number and `other` */ - + #[inline] fn lcm(&self, other: &BigInt) -> BigInt { BigInt::from_biguint(Plus, self.data.lcm(&other.data)) } /// Returns `true` if the number can be divided by `other` without leaving a remainder - + #[inline] fn is_multiple_of(&self, other: &BigInt) -> bool { self.data.is_multiple_of(&other.data) } /// Returns `true` if the number is divisible by `2` - + #[inline] fn is_even(&self) -> bool { self.data.is_even() } /// Returns `true` if the number is not divisible by `2` - + #[inline] fn is_odd(&self) -> bool { self.data.is_odd() } } impl IntConvertible for BigInt { - + #[inline] fn to_int(&self) -> int { match self.sign { Plus => num::min(self.to_uint(), int::max_value as uint) as int, @@ -1021,7 +1017,7 @@ impl IntConvertible for BigInt { } } - + #[inline] fn from_int(n: int) -> BigInt { if n > 0 { return BigInt::from_biguint(Plus, BigUint::from_uint(n as uint)); @@ -1036,7 +1032,7 @@ impl IntConvertible for BigInt { } impl ToStrRadix for BigInt { - + #[inline] fn to_str_radix(&self, radix: uint) -> ~str { match self.sign { Plus => self.data.to_str_radix(radix), @@ -1048,21 +1044,21 @@ impl ToStrRadix for BigInt { impl FromStrRadix for BigInt { /// Creates and initializes an BigInt. - - fn from_str_radix(s: &str, radix: uint) - -> Option { + #[inline] + fn from_str_radix(s: &str, radix: uint) -> Option { BigInt::parse_bytes(s.as_bytes(), radix) } } impl BigInt { /// Creates and initializes an BigInt. + #[inline] pub fn new(sign: Sign, v: ~[BigDigit]) -> BigInt { BigInt::from_biguint(sign, BigUint::new(v)) } /// Creates and initializes an BigInt. - + #[inline] pub fn from_biguint(sign: Sign, data: BigUint) -> BigInt { if sign == Zero || data.is_zero() { return BigInt { sign: Zero, data: Zero::zero() }; @@ -1071,20 +1067,19 @@ impl BigInt { } /// Creates and initializes an BigInt. - + #[inline] pub fn from_uint(n: uint) -> BigInt { if n == 0 { return Zero::zero(); } return BigInt::from_biguint(Plus, BigUint::from_uint(n)); } /// Creates and initializes an BigInt. - + #[inline] pub fn from_slice(sign: Sign, slice: &[BigDigit]) -> BigInt { BigInt::from_biguint(sign, BigUint::from_slice(slice)) } /// Creates and initializes an BigInt. - pub fn parse_bytes(buf: &[u8], radix: uint) -> Option { if buf.is_empty() { return None; } @@ -1098,6 +1093,7 @@ impl BigInt { .map_move(|bu| BigInt::from_biguint(sign, bu)); } + #[inline] pub fn to_uint(&self) -> uint { match self.sign { Plus => self.data.to_uint(), @@ -1577,7 +1573,6 @@ mod biguint_tests { #[cfg(test)] mod bigint_tests { - use super::*; use std::cmp::{Less, Equal, Greater}; From fc41ba167cac9f63eda4ee4c4927b7c905306d50 Mon Sep 17 00:00:00 2001 From: gifnksm Date: Sun, 25 Aug 2013 23:55:12 +0900 Subject: [PATCH 4/6] bigint: un-ignore test_shr --- src/libextra/num/bigint.rs | 121 ++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 63 deletions(-) diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 00eec3e9ac4..6e2a6fcbfee 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -1167,83 +1167,78 @@ mod biguint_tests { #[test] fn test_shl() { - fn check(v: ~[BigDigit], shift: uint, ans: ~[BigDigit]) { - assert_eq!(BigUint::new(v) << shift, BigUint::new(ans)); + fn check(s: &str, shift: uint, ans: &str) { + let bu = (FromStrRadix::from_str_radix::(s, 16).unwrap() << shift) + .to_str_radix(16); + assert_eq!(bu.as_slice(), ans); } - check(~[], 3, ~[]); - check(~[1, 1, 1], 3, ~[1 << 3, 1 << 3, 1 << 3]); - check(~[1 << (BigDigit::bits - 2)], 2, ~[0, 1]); - check(~[1 << (BigDigit::bits - 2)], 3, ~[0, 2]); - check(~[1 << (BigDigit::bits - 2)], 3 + BigDigit::bits, ~[0, 0, 2]); + check("0", 3, "0"); + check("1", 3, "8"); - test_shl_bits(); + check("1" + "0000" + "0000" + "0000" + "0001" + "0000" + "0000" + "0000" + "0001", 3, + "8" + "0000" + "0000" + "0000" + "0008" + "0000" + "0000" + "0000" + "0008"); + check("1" + "0000" + "0001" + "0000" + "0001", 2, + "4" + "0000" + "0004" + "0000" + "0004"); + check("1" + "0001" + "0001", 1, + "2" + "0002" + "0002"); - #[cfg(target_word_size = "64")] - fn test_shl_bits() { - check(~[0x7654_3210, 0xfedc_ba98, - 0x7654_3210, 0xfedc_ba98], 4, - ~[0x6543_2100, 0xedcb_a987, - 0x6543_210f, 0xedcb_a987, 0xf]); - check(~[0x2222_1111, 0x4444_3333, - 0x6666_5555, 0x8888_7777], 16, - ~[0x1111_0000, 0x3333_2222, - 0x5555_4444, 0x7777_6666, 0x8888]); - } + check("" + "4000" + "0000" + "0000" + "0000", 3, + "2" + "0000" + "0000" + "0000" + "0000"); + check("" + "4000" + "0000", 2, + "1" + "0000" + "0000"); + check("" + "4000", 2, + "1" + "0000"); - #[cfg(target_word_size = "32")] - fn test_shl_bits() { - check(~[0x3210, 0x7654, 0xba98, 0xfedc, - 0x3210, 0x7654, 0xba98, 0xfedc], 4, - ~[0x2100, 0x6543, 0xa987, 0xedcb, - 0x210f, 0x6543, 0xa987, 0xedcb, 0xf]); - check(~[0x1111, 0x2222, 0x3333, 0x4444, - 0x5555, 0x6666, 0x7777, 0x8888], 16, - ~[0x0000, 0x1111, 0x2222, 0x3333, - 0x4444, 0x5555, 0x6666, 0x7777, 0x8888]); - } + check("" + "4000" + "0000" + "0000" + "0000", 67, + "2" + "0000" + "0000" + "0000" + "0000" + "0000" + "0000" + "0000" + "0000"); + check("" + "4000" + "0000", 35, + "2" + "0000" + "0000" + "0000" + "0000"); + check("" + "4000", 19, + "2" + "0000" + "0000"); + check("" + "fedc" + "ba98" + "7654" + "3210" + "fedc" + "ba98" + "7654" + "3210", 4, + "f" + "edcb" + "a987" + "6543" + "210f" + "edcb" + "a987" + "6543" + "2100"); + check("88887777666655554444333322221111", 16, + "888877776666555544443333222211110000"); } #[test] - #[ignore(cfg(target_word_size = "32"))] fn test_shr() { - fn check(v: ~[BigDigit], shift: uint, ans: ~[BigDigit]) { - assert_eq!(BigUint::new(v) >> shift, BigUint::new(ans)); + fn check(s: &str, shift: uint, ans: &str) { + let bu = (FromStrRadix::from_str_radix::(s, 16).unwrap() >> shift) + .to_str_radix(16); + assert_eq!(bu.as_slice(), ans); } - check(~[], 3, ~[]); - check(~[1, 1, 1], 3, - ~[1 << (BigDigit::bits - 3), 1 << (BigDigit::bits - 3)]); - check(~[1 << 2], 2, ~[1]); - check(~[1, 2], 3, ~[1 << (BigDigit::bits - 2)]); - check(~[1, 1, 2], 3 + BigDigit::bits, ~[1 << (BigDigit::bits - 2)]); - check(~[0, 1], 1, ~[0x80000000]); - test_shr_bits(); + check("0", 3, "0"); + check("f", 3, "1"); - #[cfg(target_word_size = "64")] - fn test_shr_bits() { - check(~[0x6543_2100, 0xedcb_a987, - 0x6543_210f, 0xedcb_a987, 0xf], 4, - ~[0x7654_3210, 0xfedc_ba98, - 0x7654_3210, 0xfedc_ba98]); - check(~[0x1111_0000, 0x3333_2222, - 0x5555_4444, 0x7777_6666, 0x8888], 16, - ~[0x2222_1111, 0x4444_3333, - 0x6666_5555, 0x8888_7777]); - } + check("1" + "0000" + "0000" + "0000" + "0001" + "0000" + "0000" + "0000" + "0001", 3, + "" + "2000" + "0000" + "0000" + "0000" + "2000" + "0000" + "0000" + "0000"); + check("1" + "0000" + "0001" + "0000" + "0001", 2, + "" + "4000" + "0000" + "4000" + "0000"); + check("1" + "0001" + "0001", 1, + "" + "8000" + "8000"); - #[cfg(target_word_size = "32")] - fn test_shr_bits() { - check(~[0x2100, 0x6543, 0xa987, 0xedcb, - 0x210f, 0x6543, 0xa987, 0xedcb, 0xf], 4, - ~[0x3210, 0x7654, 0xba98, 0xfedc, - 0x3210, 0x7654, 0xba98, 0xfedc]); - check(~[0x0000, 0x1111, 0x2222, 0x3333, - 0x4444, 0x5555, 0x6666, 0x7777, 0x8888], 16, - ~[0x1111, 0x2222, 0x3333, 0x4444, - 0x5555, 0x6666, 0x7777, 0x8888]); - } + check("2" + "0000" + "0000" + "0000" + "0001" + "0000" + "0000" + "0000" + "0001", 67, + "" + "4000" + "0000" + "0000" + "0000"); + check("2" + "0000" + "0001" + "0000" + "0001", 35, + "" + "4000" + "0000"); + check("2" + "0001" + "0001", 19, + "" + "4000"); + + check("1" + "0000" + "0000" + "0000" + "0000", 1, + "" + "8000" + "0000" + "0000" + "0000"); + check("1" + "0000" + "0000", 1, + "" + "8000" + "0000"); + check("1" + "0000", 1, + "" + "8000"); + check("f" + "edcb" + "a987" + "6543" + "210f" + "edcb" + "a987" + "6543" + "2100", 4, + "" + "fedc" + "ba98" + "7654" + "3210" + "fedc" + "ba98" + "7654" + "3210"); + + check("888877776666555544443333222211110000", 16, + "88887777666655554444333322221111"); } #[test] From 084cfc10f5bea02f6bd32856eb2c343692af25c9 Mon Sep 17 00:00:00 2001 From: gifnksm Date: Mon, 26 Aug 2013 00:26:03 +0900 Subject: [PATCH 5/6] bigint: Add benchmarks --- src/libextra/num/bigint.rs | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 6e2a6fcbfee..6c8011f2b9e 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -1983,3 +1983,47 @@ mod bigint_tests { assert_eq!(-Zero::zero::(), Zero::zero::()); } } + +#[cfg(test)] +mod bench { + use super::*; + use std::{iterator, util}; + use std::num::{Zero, One}; + use extra::test::BenchHarness; + + fn factorial(n: uint) -> BigUint { + let mut f = One::one::(); + for i in iterator::range_inclusive(1, n) { + f = f * BigUint::from_uint(i); + } + f + } + + fn fib(n: uint) -> BigUint { + let mut f0 = Zero::zero::(); + let mut f1 = One::one::(); + for _ in range(0, n) { + let f2 = f0 + f1; + f0 = util::replace(&mut f1, f2); + } + f0 + } + + #[bench] + fn factorial_100(bh: &mut BenchHarness) { + do bh.iter { factorial(100); } + } + + #[bench] + fn fib_500(bh: &mut BenchHarness) { + do bh.iter { fib(100); } + } + + #[bench] + fn to_str(bh: &mut BenchHarness) { + let fac = factorial(100); + let fib = fib(100); + do bh.iter { fac.to_str(); } + do bh.iter { fib.to_str(); } + } +} From f8f17a39ceb74cbd55006c389f1925c0e9ed8eab Mon Sep 17 00:00:00 2001 From: gifnksm Date: Mon, 26 Aug 2013 20:27:20 +0900 Subject: [PATCH 6/6] bigint: fix wrong benchmark fn name --- src/libextra/num/bigint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 6c8011f2b9e..9222dea13c4 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -2015,7 +2015,7 @@ mod bench { } #[bench] - fn fib_500(bh: &mut BenchHarness) { + fn fib_100(bh: &mut BenchHarness) { do bh.iter { fib(100); } }