about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libextra/num/bigint.rs442
1 files changed, 210 insertions, 232 deletions
diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs
index c86c4dd07ed..9222dea13c4 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,31 +48,29 @@ 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;
     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)
     }
@@ -92,40 +88,26 @@ pub struct BigUint {
 }
 
 impl Eq for BigUint {
-
+    #[inline]
     fn eq(&self, other: &BigUint) -> bool { self.equals(other) }
-
-    fn ne(&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}
     }
-
-    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 {
-
+    #[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; }
@@ -140,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<BigUint> {
         FromStrRadix::from_str_radix(s, 10)
     }
@@ -154,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() }
@@ -172,7 +154,7 @@ impl Orderable for BigUint {
 }
 
 impl Shl<uint, BigUint> for BigUint {
-
+    #[inline]
     fn shl(&self, rhs: &uint) -> BigUint {
         let n_unit = *rhs / BigDigit::bits;
         let n_bits = *rhs % BigDigit::bits;
@@ -181,7 +163,7 @@ impl Shl<uint, BigUint> for BigUint {
 }
 
 impl Shr<uint, BigUint> for BigUint {
-
+    #[inline]
     fn shr(&self, rhs: &uint) -> BigUint {
         let n_unit = *rhs / BigDigit::bits;
         let n_bits = *rhs % BigDigit::bits;
@@ -190,22 +172,21 @@ impl Shr<uint, BigUint> 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<BigUint, BigUint> for BigUint {
-
     fn add(&self, other: &BigUint) -> BigUint {
         let new_len = num::max(self.data.len(), other.data.len());
 
@@ -225,7 +206,6 @@ impl Add<BigUint, BigUint> for BigUint {
 }
 
 impl Sub<BigUint, BigUint> for BigUint {
-
     fn sub(&self, other: &BigUint) -> BigUint {
         let new_len = num::max(self.data.len(), other.data.len());
 
@@ -298,14 +278,14 @@ impl Mul<BigUint, BigUint> 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),
@@ -317,7 +297,7 @@ impl Mul<BigUint, BigUint> for BigUint {
 }
 
 impl Div<BigUint, BigUint> for BigUint {
-
+    #[inline]
     fn div(&self, other: &BigUint) -> BigUint {
         let (q, _) = self.div_rem(other);
         return q;
@@ -325,7 +305,7 @@ impl Div<BigUint, BigUint> for BigUint {
 }
 
 impl Rem<BigUint, BigUint> for BigUint {
-
+    #[inline]
     fn rem(&self, other: &BigUint) -> BigUint {
         let (_, r) = self.div_rem(other);
         return r;
@@ -333,29 +313,28 @@ impl Rem<BigUint, BigUint> for BigUint {
 }
 
 impl Neg<BigUint> 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()); }
@@ -443,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();
@@ -459,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() {
@@ -478,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);
@@ -504,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 = ~[];
@@ -520,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);
@@ -536,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> {
         BigUint::parse_bytes(s.as_bytes(), radix)
@@ -545,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);
@@ -557,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(),
@@ -567,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<BigUint> {
         let (base, unit_len) = get_radix_base(radix);
@@ -603,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,
@@ -612,7 +588,7 @@ impl BigUint {
         }
     }
 
-
+    #[inline]
     fn shl_unit(&self, n_unit: uint) -> BigUint {
         if n_unit == 0 || self.is_zero() { return (*self).clone(); }
 
@@ -620,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(); }
 
@@ -636,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(); }
@@ -645,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(); }
 
@@ -659,8 +635,8 @@ impl BigUint {
     }
 }
 
-#[cfg(target_arch = "x86_64")]
-
+#[cfg(target_word_size = "64")]
+#[inline]
 fn get_radix_base(radix: uint) -> (uint, uint) {
     assert!(1 < radix && radix <= 16);
     match radix {
@@ -683,10 +659,8 @@ 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")]
+#[inline]
 fn get_radix_base(radix: uint) -> (uint, uint) {
     assert!(1 < radix && radix <= 16);
     match radix {
@@ -714,31 +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}
     }
-
-    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 {
-    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,
@@ -750,7 +711,7 @@ impl TotalOrd for Sign {
 
 impl Neg<Sign> for Sign {
     /// Negate Sign value.
-
+    #[inline]
     fn neg(&self) -> Sign {
         match *self {
           Minus => Plus,
@@ -768,40 +729,26 @@ pub struct BigInt {
 }
 
 impl Eq for BigInt {
-
+    #[inline]
     fn eq(&self, other: &BigInt) -> bool { self.equals(other) }
-
-    fn ne(&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}
     }
-
-    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 {
-
+    #[inline]
     fn cmp(&self, other: &BigInt) -> Ordering {
         let scmp = self.sign.cmp(&other.sign);
         if scmp != Equal { return scmp; }
@@ -815,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<BigInt> {
         FromStrRadix::from_str_radix(s, 10)
     }
@@ -829,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() }
@@ -847,38 +794,38 @@ impl Orderable for BigInt {
 }
 
 impl Shl<uint, BigInt> for BigInt {
-
+    #[inline]
     fn shl(&self, rhs: &uint) -> BigInt {
         BigInt::from_biguint(self.sign, self.data << *rhs)
     }
 }
 
 impl Shr<uint, BigInt> 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(),
@@ -886,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()),
@@ -900,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<BigInt, BigInt> for BigInt {
-
+    #[inline]
     fn add(&self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
             (Zero, _)      => other.clone(),
@@ -923,7 +870,7 @@ impl Add<BigInt, BigInt> for BigInt {
 }
 
 impl Sub<BigInt, BigInt> for BigInt {
-
+    #[inline]
     fn sub(&self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
             (Zero, _)    => -other,
@@ -941,7 +888,7 @@ impl Sub<BigInt, BigInt> for BigInt {
 }
 
 impl Mul<BigInt, BigInt> for BigInt {
-
+    #[inline]
     fn mul(&self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
             (Zero, _)     | (_,     Zero)  => Zero::zero(),
@@ -956,7 +903,7 @@ impl Mul<BigInt, BigInt> for BigInt {
 }
 
 impl Div<BigInt, BigInt> for BigInt {
-
+    #[inline]
     fn div(&self, other: &BigInt) -> BigInt {
         let (q, _) = self.div_rem(other);
         return q;
@@ -964,7 +911,7 @@ impl Div<BigInt, BigInt> for BigInt {
 }
 
 impl Rem<BigInt, BigInt> for BigInt {
-
+    #[inline]
     fn rem(&self, other: &BigInt) -> BigInt {
         let (_, r) = self.div_rem(other);
         return r;
@@ -972,14 +919,14 @@ impl Rem<BigInt, BigInt> for BigInt {
 }
 
 impl Neg<BigInt> 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);
@@ -994,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);
@@ -1034,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))
     }
@@ -1042,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,
@@ -1071,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));
@@ -1086,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),
@@ -1098,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<BigInt> {
+    #[inline]
+    fn from_str_radix(s: &str, radix: uint) -> Option<BigInt> {
         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() };
@@ -1121,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<BigInt> {
         if buf.is_empty() { return None; }
@@ -1148,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(),
@@ -1221,89 +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));
-        }
-
-        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]);
-
-        test_shl_bits();
-
-        #[cfg(target_arch = "x86_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]);
-        }
-
-        #[cfg(target_arch = "arm")]
-        #[cfg(target_arch = "x86")]
-        #[cfg(target_arch = "mips")]
-        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]);
-        }
-
+        fn check(s: &str, shift: uint, ans: &str) {
+            let bu = (FromStrRadix::from_str_radix::<BigUint>(s, 16).unwrap() << shift)
+                .to_str_radix(16);
+            assert_eq!(bu.as_slice(), ans);
+        }
+
+        check("0", 3, "0");
+        check("1", 3, "8");
+
+        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");
+
+        check(""  + "4000" + "0000" + "0000" + "0000", 3,
+              "2" + "0000" + "0000" + "0000" + "0000");
+        check(""  + "4000" + "0000", 2,
+              "1" + "0000" + "0000");
+        check(""  + "4000", 2,
+              "1" + "0000");
+
+        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_arch = "x86"))]
-    #[ignore(cfg(target_arch = "arm"))]
-    #[ignore(cfg(target_arch = "mips"))]
     fn test_shr() {
-        fn check(v: ~[BigDigit], shift: uint, ans: ~[BigDigit]) {
-            assert_eq!(BigUint::new(v) >> shift, BigUint::new(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();
-
-        #[cfg(target_arch = "x86_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]);
-        }
-
-        #[cfg(target_arch = "arm")]
-        #[cfg(target_arch = "x86")]
-        #[cfg(target_arch = "mips")]
-        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]);
-        }
+        fn check(s: &str, shift: uint, ans: &str) {
+            let bu = (FromStrRadix::from_str_radix::<BigUint>(s, 16).unwrap() >> shift)
+                .to_str_radix(16);
+            assert_eq!(bu.as_slice(), ans);
+        }
+
+        check("0", 3, "0");
+        check("f", 3, "1");
+
+        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");
+
+        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]
@@ -1633,7 +1568,6 @@ mod biguint_tests {
 
 #[cfg(test)]
 mod bigint_tests {
-
     use super::*;
 
     use std::cmp::{Less, Equal, Greater};
@@ -2049,3 +1983,47 @@ mod bigint_tests {
         assert_eq!(-Zero::zero::<BigInt>(), Zero::zero::<BigInt>());
     }
 }
+
+#[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::<BigUint>();
+        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::<BigUint>();
+        let mut f1 = One::one::<BigUint>();
+        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_100(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(); }
+    }
+}