(index<- )        ./libnum/bigint.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
    1  // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
    2  // file at the top-level directory of this distribution and at
    3  // http://rust-lang.org/COPYRIGHT.
    4  //
    5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
    6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
    8  // option. This file may not be copied, modified, or distributed
    9  // except according to those terms.
   10  
   11  /*!
   12  
   13  A Big integer (signed version: `BigInt`, unsigned version: `BigUint`).
   14  
   15  A `BigUint` is represented as an array of `BigDigit`s.
   16  A `BigInt` is a combination of `BigUint` and `Sign`.
   17  */
   18  
   19  use Integer;
   20  
   21  use std::cmp;
   22  use std::fmt;
   23  use std::from_str::FromStr;
   24  use std::num::CheckedDiv;
   25  use std::num::{Bitwise, ToPrimitive, FromPrimitive};
   26  use std::num::{Zero, One, ToStrRadix, FromStrRadix};
   27  use rand::Rng;
   28  use std::strbuf::StrBuf;
   29  use std::uint;
   30  use std::{i64, u64};
   31  
   32  /**
   33  A `BigDigit` is a `BigUint`'s composing element.
   34  */
   35  pub type BigDigit = u32;
   36  
   37  /**
   38  A `DoubleBigDigit` is the internal type used to do the computations.  Its
   39  size is the double of the size of `BigDigit`.
   40  */
   41  pub type DoubleBigDigit = u64;
   42  
   43  pub static ZERO_BIG_DIGIT: BigDigit = 0;
   44  static ZERO_VEC: [BigDigit, ..1] = [ZERO_BIG_DIGIT];
   45  
   46  pub mod BigDigit {
   47      use super::BigDigit;
   48      use super::DoubleBigDigit;
   49  
   50      // `DoubleBigDigit` size dependent
   51      pub static bits: uint = 32;
   52  
   53      pub static base: DoubleBigDigit = 1 << bits;
   54      static lo_mask: DoubleBigDigit = (-1 as DoubleBigDigit) >> bits;
   55  
   56      #[inline]
   57      fn get_hi(nDoubleBigDigit) -> BigDigit { (n >> bits) as BigDigit }
   58      #[inline]
   59      fn get_lo(nDoubleBigDigit) -> BigDigit { (n & lo_mask) as BigDigit }
   60  
   61      /// Split one `DoubleBigDigit` into two `BigDigit`s.
   62      #[inline]
   63      pub fn from_doublebigdigit(nDoubleBigDigit) -> (BigDigit, BigDigit) {
   64          (get_hi(n), get_lo(n))
   65      }
   66  
   67      /// Join two `BigDigit`s into one `DoubleBigDigit`
   68      #[inline]
   69      pub fn to_doublebigdigit(hiBigDigit, loBigDigit) -> DoubleBigDigit {
   70          (lo as DoubleBigDigit) | ((hi as DoubleBigDigit) << bits)
   71      }
   72  }
   73  
   74  /**
   75  A big unsigned integer type.
   76  
   77  A `BigUint`-typed value `BigUint { data: vec!(a, b, c) }` represents a number
   78  `(a + b * BigDigit::base + c * BigDigit::base^2)`.
   79  */
   80  #[deriving(Clone)]
   81  pub struct BigUint {
   82      data: Vec<BigDigit>
   83  }
   84  
   85  impl Eq for BigUint {
   86      #[inline]
   87      fn eq(&self, other&BigUint) -> bool {
   88          match self.cmp(other) { Equal => true, _ => false }
   89      }
   90  }
   91  impl TotalEq for BigUint {}
   92  
   93  impl Ord for BigUint {
   94      #[inline]
   95      fn lt(&self, other&BigUint) -> bool {
   96          match self.cmp(other) { Less => true, _ => false}
   97      }
   98  }
   99  
  100  impl TotalOrd for BigUint {
  101      #[inline]
  102      fn cmp(&self, other&BigUint) -> Ordering {
  103          let (s_len, o_len) = (self.data.len(), other.data.len());
  104          if s_len < o_len { return Less; }
  105          if s_len > o_len { return Greater;  }
  106  
  107          for (&self_i, &other_i) in self.data.iter().rev().zip(other.data.iter().rev()) {
  108              if self_i < other_i { return Less; }
  109              if self_i > other_i { return Greater; }
  110          }
  111          return Equal;
  112      }
  113  }
  114  
  115  impl fmt::Show for BigUint {
  116      fn fmt(&self, f&mut fmt::Formatter) -> fmt::Result {
  117          write!(f.buf, "{}", self.to_str_radix(10))
  118      }
  119  }
  120  
  121  impl FromStr for BigUint {
  122      #[inline]
  123      fn from_str(s&str) -> Option<BigUint> {
  124          FromStrRadix::from_str_radix(s, 10)
  125      }
  126  }
  127  
  128  impl Num for BigUint {}
  129  
  130  impl BitAnd<BigUint, BigUint> for BigUint {
  131      fn bitand(&self, other&BigUint) -> BigUint {
  132          BigUint::new(self.data.iter().zip(other.data.iter()).map(|(ai, bi)| *ai & *bi).collect())
  133      }
  134  }
  135  
  136  impl BitOr<BigUint, BigUint> for BigUint {
  137      fn bitor(&self, other&BigUint) -> BigUint {
  138          let zeros = ZERO_VEC.iter().cycle();
  139          let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
  140          let ored = a.data.iter().zip(b.data.iter().chain(zeros)).map(
  141              |(ai, bi)| *ai | *bi
  142          ).collect();
  143          return BigUint::new(ored);
  144      }
  145  }
  146  
  147  impl BitXor<BigUint, BigUint> for BigUint {
  148      fn bitxor(&self, other&BigUint) -> BigUint {
  149          let zeros = ZERO_VEC.iter().cycle();
  150          let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
  151          let xored = a.data.iter().zip(b.data.iter().chain(zeros)).map(
  152              |(ai, bi)| *ai ^ *bi
  153          ).collect();
  154          return BigUint::new(xored);
  155      }
  156  }
  157  
  158  impl Shl<uint, BigUint> for BigUint {
  159      #[inline]
  160      fn shl(&self, rhs&uint) -> BigUint {
  161          let n_unit = *rhs / BigDigit::bits;
  162          let n_bits = *rhs % BigDigit::bits;
  163          return self.shl_unit(n_unit).shl_bits(n_bits);
  164      }
  165  }
  166  
  167  impl Shr<uint, BigUint> for BigUint {
  168      #[inline]
  169      fn shr(&self, rhs&uint) -> BigUint {
  170          let n_unit = *rhs / BigDigit::bits;
  171          let n_bits = *rhs % BigDigit::bits;
  172          return self.shr_unit(n_unit).shr_bits(n_bits);
  173      }
  174  }
  175  
  176  impl Zero for BigUint {
  177      #[inline]
  178      fn zero() -> BigUint { BigUint::new(Vec::new()) }
  179  
  180      #[inline]
  181      fn is_zero(&self) -> bool { self.data.is_empty() }
  182  }
  183  
  184  impl One for BigUint {
  185      #[inline]
  186      fn one() -> BigUint { BigUint::new(vec!(1)) }
  187  }
  188  
  189  impl Unsigned for BigUint {}
  190  
  191  impl Add<BigUint, BigUint> for BigUint {
  192      fn add(&self, other&BigUint) -> BigUint {
  193          let zeros = ZERO_VEC.iter().cycle();
  194          let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
  195  
  196          let mut carry = 0;
  197          let mut sumVec<BigDigit> =  a.data.iter().zip(b.data.iter().chain(zeros)).map(|(ai, bi)| {
  198              let (hi, lo) = BigDigit::from_doublebigdigit(
  199                  (*ai as DoubleBigDigit) + (*bi as DoubleBigDigit) + (carry as DoubleBigDigit));
  200              carry = hi;
  201              lo
  202          }).collect();
  203          if carry != 0 { sum.push(carry); }
  204          return BigUint::new(sum);
  205      }
  206  }
  207  
  208  impl Sub<BigUint, BigUint> for BigUint {
  209      fn sub(&self, other&BigUint) -> BigUint {
  210          let new_len = cmp::max(self.data.len(), other.data.len());
  211          let zeros = ZERO_VEC.iter().cycle();
  212          let (a, b) = (self.data.iter().chain(zeros.clone()), other.data.iter().chain(zeros));
  213  
  214          let mut borrow = 0;
  215          let diffVec<BigDigit> =  a.take(new_len).zip(b).map(|(ai, bi)| {
  216              let (hi, lo) = BigDigit::from_doublebigdigit(
  217                  BigDigit::base
  218                      + (*ai as DoubleBigDigit)
  219                      - (*bi as DoubleBigDigit)
  220                      - (borrow as DoubleBigDigit)
  221              );
  222              /*
  223              hi * (base) + lo == 1*(base) + ai - bi - borrow
  224              => ai - bi - borrow < 0 <=> hi == 0
  225              */
  226              borrow = if hi == 0 { 1 } else { 0 };
  227              lo
  228          }).collect();
  229  
  230          assert!(borrow == 0,
  231                  "Cannot subtract other from self because other is larger than self.");
  232          return BigUint::new(diff);
  233      }
  234  }
  235  
  236  impl Mul<BigUint, BigUint> for BigUint {
  237      fn mul(&self, other&BigUint) -> BigUint {
  238          if self.is_zero() || other.is_zero() { return Zero::zero(); }
  239  
  240          let (s_len, o_len) = (self.data.len(), other.data.len());
  241          if s_len == 1 { return mul_digit(other, self.data.as_slice()[0]);  }
  242          if o_len == 1 { return mul_digit(self,  other.data.as_slice()[0]); }
  243  
  244          // Using Karatsuba multiplication
  245          // (a1 * base + a0) * (b1 * base + b0)
  246          // = a1*b1 * base^2 +
  247          //   (a1*b1 + a0*b0 - (a1-b0)*(b1-a0)) * base +
  248          //   a0*b0
  249          let half_len = cmp::max(s_len, o_len) / 2;
  250          let (s_hi, s_lo) = cut_at(self,  half_len);
  251          let (o_hi, o_lo) = cut_at(other, half_len);
  252  
  253          let ll = s_lo * o_lo;
  254          let hh = s_hi * o_hi;
  255          let mm = {
  256              let (s1, n1) = sub_sign(s_hi, s_lo);
  257              let (s2, n2) = sub_sign(o_hi, o_lo);
  258              match (s1, s2) {
  259                  (Equal, _) | (_, Equal) => hh + ll,
  260                  (Less, Greater) | (Greater, Less) => hh + ll + (n1 * n2),
  261                  (Less, Less) | (Greater, Greater) => hh + ll - (n1 * n2)
  262              }
  263          };
  264  
  265          return ll + mm.shl_unit(half_len) + hh.shl_unit(half_len * 2);
  266  
  267  
  268          fn mul_digit(a&BigUint, nBigDigit) -> BigUint {
  269              if n == 0 { return Zero::zero(); }
  270              if n == 1 { return (*a).clone(); }
  271  
  272              let mut carry = 0;
  273              let mut prodVec<BigDigit> = a.data.iter().map(|ai| {
  274                  let (hi, lo) = BigDigit::from_doublebigdigit(
  275                      (*ai as DoubleBigDigit) * (n as DoubleBigDigit) + (carry as DoubleBigDigit)
  276                  );
  277                  carry = hi;
  278                  lo
  279              }).collect();
  280              if carry != 0 { prod.push(carry); }
  281              return BigUint::new(prod);
  282          }
  283  
  284          #[inline]
  285          fn cut_at(a&BigUint, nuint) -> (BigUint, BigUint) {
  286              let mid = cmp::min(a.data.len(), n);
  287              return (BigUint::from_slice(a.data.slice(mid, a.data.len())),
  288                      BigUint::from_slice(a.data.slice(0, mid)));
  289          }
  290  
  291          #[inline]
  292          fn sub_sign(aBigUint, bBigUint) -> (Ordering, BigUint) {
  293              match a.cmp(&b) {
  294                  Less    => (Less,    b - a),
  295                  Greater => (Greater, a - b),
  296                  _       => (Equal,   Zero::zero())
  297              }
  298          }
  299      }
  300  }
  301  
  302  impl Div<BigUint, BigUint> for BigUint {
  303      #[inline]
  304      fn div(&self, other&BigUint) -> BigUint {
  305          let (q, _) = self.div_rem(other);
  306          return q;
  307      }
  308  }
  309  
  310  impl Rem<BigUint, BigUint> for BigUint {
  311      #[inline]
  312      fn rem(&self, other&BigUint) -> BigUint {
  313          let (_, r) = self.div_rem(other);
  314          return r;
  315      }
  316  }
  317  
  318  impl Neg<BigUint> for BigUint {
  319      #[inline]
  320      fn neg(&self) -> BigUint { fail!() }
  321  }
  322  
  323  impl CheckedAdd for BigUint {
  324      #[inline]
  325      fn checked_add(&self, v&BigUint) -> Option<BigUint> {
  326          return Some(self.add(v));
  327      }
  328  }
  329  
  330  impl CheckedSub for BigUint {
  331      #[inline]
  332      fn checked_sub(&self, v&BigUint) -> Option<BigUint> {
  333          if *self < *v {
  334              return None;
  335          }
  336          return Some(self.sub(v));
  337      }
  338  }
  339  
  340  impl CheckedMul for BigUint {
  341      #[inline]
  342      fn checked_mul(&self, v&BigUint) -> Option<BigUint> {
  343          return Some(self.mul(v));
  344      }
  345  }
  346  
  347  impl CheckedDiv for BigUint {
  348      #[inline]
  349      fn checked_div(&self, v&BigUint) -> Option<BigUint> {
  350          if v.is_zero() {
  351              return None;
  352          }
  353          return Some(self.div(v));
  354      }
  355  }
  356  
  357  impl Integer for BigUint {
  358      #[inline]
  359      fn div_rem(&self, other&BigUint) -> (BigUint, BigUint) {
  360          self.div_mod_floor(other)
  361      }
  362  
  363      #[inline]
  364      fn div_floor(&self, other&BigUint) -> BigUint {
  365          let (d, _) = self.div_mod_floor(other);
  366          return d;
  367      }
  368  
  369      #[inline]
  370      fn mod_floor(&self, other&BigUint) -> BigUint {
  371          let (_, m) = self.div_mod_floor(other);
  372          return m;
  373      }
  374  
  375      fn div_mod_floor(&self, other&BigUint) -> (BigUint, BigUint) {
  376          if other.is_zero() { fail!() }
  377          if self.is_zero() { return (Zero::zero(), Zero::zero()); }
  378          if *other == One::one() { return ((*self).clone(), Zero::zero()); }
  379  
  380          match self.cmp(other) {
  381              Less    => return (Zero::zero(), (*self).clone()),
  382              Equal   => return (One::one(), Zero::zero()),
  383              Greater => {} // Do nothing
  384          }
  385  
  386          let mut shift = 0;
  387          let mut n = *other.data.last().unwrap();
  388          while n < (1 << BigDigit::bits - 2) {
  389              n <<= 1;
  390              shift += 1;
  391          }
  392          assert!(shift < BigDigit::bits);
  393          let (d, m) = div_mod_floor_inner(self << shift, other << shift);
  394          return (d, m >> shift);
  395  
  396  
  397          fn div_mod_floor_inner(aBigUint, bBigUint) -> (BigUint, BigUint) {
  398              let mut m = a;
  399              let mut dBigUint = Zero::zero();
  400              let mut n = 1;
  401              while m >= b {
  402                  let (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
  403                  let mut d0 = d0;
  404                  let mut prod = b * d0;
  405                  while prod > m {
  406                      // FIXME(#5992): assignment operator overloads
  407                      // d0 -= d_unit
  408                      d0   = d0 - d_unit;
  409                      // FIXME(#5992): assignment operator overloads
  410                      // prod -= b_unit;
  411                      prod = prod - b_unit
  412                  }
  413                  if d0.is_zero() {
  414                      n = 2;
  415                      continue;
  416                  }
  417                  n = 1;
  418                  // FIXME(#5992): assignment operator overloads
  419                  // d += d0;
  420                  d = d + d0;
  421                  // FIXME(#5992): assignment operator overloads
  422                  // m -= prod;
  423                  m = m - prod;
  424              }
  425              return (d, m);
  426          }
  427  
  428  
  429          fn div_estimate(a&BigUint, b&BigUint, nuint)
  430              -> (BigUint, BigUint, BigUint) {
  431              if a.data.len() < n {
  432                  return (Zero::zero(), Zero::zero(), (*a).clone());
  433              }
  434  
  435              let an = a.data.tailn(a.data.len() - n);
  436              let bn = *b.data.last().unwrap();
  437              let mut d = Vec::with_capacity(an.len());
  438              let mut carry = 0;
  439              for elt in an.iter().rev() {
  440                  let ai = BigDigit::to_doublebigdigit(carry, *elt);
  441                  let di = ai / (bn as DoubleBigDigit);
  442                  assert!(di < BigDigit::base);
  443                  carry = (ai % (bn as DoubleBigDigit)) as BigDigit;
  444                  d.push(di as BigDigit)
  445              }
  446              d.reverse();
  447  
  448              let shift = (a.data.len() - an.len()) - (b.data.len() - 1);
  449              if shift == 0 {
  450                  return (BigUint::new(d), One::one(), (*b).clone());
  451              }
  452              let oneBigUint = One::one();
  453              return (BigUint::new(d).shl_unit(shift),
  454                      one.shl_unit(shift),
  455                      b.shl_unit(shift));
  456          }
  457      }
  458  
  459      /**
  460       * Calculates the Greatest Common Divisor (GCD) of the number and `other`
  461       *
  462       * The result is always positive
  463       */
  464      #[inline]
  465      fn gcd(&self, other&BigUint) -> BigUint {
  466          // Use Euclid's algorithm
  467          let mut m = (*self).clone();
  468          let mut n = (*other).clone();
  469          while !m.is_zero() {
  470              let temp = m;
  471              m = n % temp;
  472              n = temp;
  473          }
  474          return n;
  475      }
  476  
  477      /**
  478       * Calculates the Lowest Common Multiple (LCM) of the number and `other`
  479       */
  480      #[inline]
  481      fn lcm(&self, other&BigUint) -> BigUint { ((*self * *other) / self.gcd(other)) }
  482  
  483      /// Returns `true` if the number can be divided by `other` without leaving a remainder
  484      #[inline]
  485      fn divides(&self, other&BigUint) -> bool { (*self % *other).is_zero() }
  486  
  487      /// Returns `true` if the number is divisible by `2`
  488      #[inline]
  489      fn is_even(&self) -> bool {
  490          // Considering only the last digit.
  491          match self.data.as_slice().head() {
  492              Some(x) => x.is_even(),
  493              None => true
  494          }
  495      }
  496  
  497      /// Returns `true` if the number is not divisible by `2`
  498      #[inline]
  499      fn is_odd(&self) -> bool { !self.is_even() }
  500  }
  501  
  502  impl ToPrimitive for BigUint {
  503      #[inline]
  504      fn to_i64(&self) -> Option<i64> {
  505          self.to_u64().and_then(|n| {
  506              // If top bit of u64 is set, it's too large to convert to i64.
  507              if n >> 63 == 0 {
  508                  Some(n as i64)
  509              } else {
  510                  None
  511              }
  512          })
  513      }
  514  
  515      // `DoubleBigDigit` size dependent
  516      #[inline]
  517      fn to_u64(&self) -> Option<u64> {
  518          match self.data.len() {
  519              0 => Some(0),
  520              1 => Some(self.data.as_slice()[0] as u64),
  521              2 => Some(BigDigit::to_doublebigdigit(self.data.as_slice()[1], self.data.as_slice()[0])
  522                        as u64),
  523              _ => None
  524          }
  525      }
  526  }
  527  
  528  impl FromPrimitive for BigUint {
  529      #[inline]
  530      fn from_i64(ni64) -> Option<BigUint> {
  531          if n > 0 {
  532              FromPrimitive::from_u64(n as u64)
  533          } else if n == 0 {
  534              Some(Zero::zero())
  535          } else {
  536              None
  537          }
  538      }
  539  
  540      // `DoubleBigDigit` size dependent
  541      #[inline]
  542      fn from_u64(nu64) -> Option<BigUint> {
  543          let n = match BigDigit::from_doublebigdigit(n) {
  544              (0,  0)  => Zero::zero(),
  545              (0,  n0) => BigUint::new(vec!(n0)),
  546              (n1, n0) => BigUint::new(vec!(n0, n1))
  547          };
  548          Some(n)
  549      }
  550  }
  551  
  552  /// A generic trait for converting a value to a `BigUint`.
  553  pub trait ToBigUint {
  554      /// Converts the value of `self` to a `BigUint`.
  555      fn to_biguint(&self) -> Option<BigUint>;
  556  }
  557  
  558  impl ToBigUint for BigInt {
  559      #[inline]
  560      fn to_biguint(&self) -> Option<BigUint> {
  561          if self.sign == Plus {
  562              Some(self.data.clone())
  563          } else if self.sign == Zero {
  564              Some(Zero::zero())
  565          } else {
  566              None
  567          }
  568      }
  569  }
  570  
  571  impl ToBigUint for BigUint {
  572      #[inline]
  573      fn to_biguint(&self) -> Option<BigUint> {
  574          Some(self.clone())
  575      }
  576  }
  577  
  578  macro_rules! impl_to_biguint(
  579      ($T:ty, $from_ty:path) => {
  580          impl ToBigUint for $T {
  581              #[inline]
  582              fn to_biguint(&self) -> Option<BigUint> {
  583                  $from_ty(*self)
  584              }
  585          }
  586      }
  587  )
  588  
  589  impl_to_biguint!(int,  FromPrimitive::from_int)
  590  impl_to_biguint!(i8,   FromPrimitive::from_i8)
  591  impl_to_biguint!(i16,  FromPrimitive::from_i16)
  592  impl_to_biguint!(i32,  FromPrimitive::from_i32)
  593  impl_to_biguint!(i64,  FromPrimitive::from_i64)
  594  impl_to_biguint!(uint, FromPrimitive::from_uint)
  595  impl_to_biguint!(u8,   FromPrimitive::from_u8)
  596  impl_to_biguint!(u16,  FromPrimitive::from_u16)
  597  impl_to_biguint!(u32,  FromPrimitive::from_u32)
  598  impl_to_biguint!(u64,  FromPrimitive::from_u64)
  599  
  600  impl ToStrRadix for BigUint {
  601      fn to_str_radix(&self, radixuint) -> ~str {
  602          assert!(1 < radix && radix <= 16);
  603          let (base, max_len) = get_radix_base(radix);
  604          if base == BigDigit::base {
  605              return fill_concat(self.data.as_slice(), radix, max_len)
  606          }
  607          return fill_concat(convert_base(self, base).as_slice(), radix, max_len);
  608  
  609          fn convert_base(n: &BigUint, baseDoubleBigDigit) -> Vec<BigDigit> {
  610              let divider    = base.to_biguint().unwrap();
  611              let mut result = Vec::new();
  612              let mut m      = n.clone();
  613              while m >= divider {
  614                  let (d, m0) = m.div_mod_floor(&divider);
  615                  result.push(m0.to_uint().unwrap() as BigDigit);
  616                  m = d;
  617              }
  618              if !m.is_zero() {
  619                  result.push(m.to_uint().unwrap() as BigDigit);
  620              }
  621              return result;
  622          }
  623  
  624          fn fill_concat(v&[BigDigit], radixuint, luint) -> ~str {
  625              if v.is_empty() { return "0".to_owned() }
  626              let mut s = StrBuf::with_capacity(v.len() * l);
  627              for n in v.iter().rev() {
  628                  let ss = (*n as uint).to_str_radix(radix);
  629                  s.push_str("0".repeat(l - ss.len()));
  630                  s.push_str(ss);
  631              }
  632              s.as_slice().trim_left_chars('0').to_owned()
  633          }
  634      }
  635  }
  636  
  637  impl FromStrRadix for BigUint {
  638      /// Creates and initializes a `BigUint`.
  639      #[inline]
  640      fn from_str_radix(s&str, radixuint)
  641          -> Option<BigUint> {
  642          BigUint::parse_bytes(s.as_bytes(), radix)
  643      }
  644  }
  645  
  646  impl BigUint {
  647      /// Creates and initializes a `BigUint`.
  648      #[inline]
  649      pub fn new(vVec<BigDigit>) -> BigUint {
  650          // omit trailing zeros
  651          let new_len = v.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1);
  652  
  653          if new_len == v.len() { return BigUint { data: v }; }
  654          let mut v = v;
  655          v.truncate(new_len);
  656          return BigUint { data: v };
  657      }
  658  
  659      /// Creates and initializes a `BigUint`.
  660      #[inline]
  661      pub fn from_slice(slice&[BigDigit]) -> BigUint {
  662          return BigUint::new(Vec::from_slice(slice));
  663      }
  664  
  665      /// Creates and initializes a `BigUint`.
  666      pub fn parse_bytes(buf&[u8], radixuint) -> Option<BigUint> {
  667          let (base, unit_len) = get_radix_base(radix);
  668          let base_num = match base.to_biguint() {
  669              Some(base_num) => base_num,
  670              None => { return None; }
  671          };
  672  
  673          let mut end             = buf.len();
  674          let mut nBigUint      = Zero::zero();
  675          let mut powerBigUint  = One::one();
  676          loop {
  677              let start = cmp::max(end, unit_len) - unit_len;
  678              match uint::parse_bytes(buf.slice(start, end), radix) {
  679                  Some(d) => {
  680                      let dOption<BigUint> = FromPrimitive::from_uint(d);
  681                      match d {
  682                          Some(d) => {
  683                              // FIXME(#5992): assignment operator overloads
  684                              // n += d * power;
  685                              n = n + d * power;
  686                          }
  687                          None => { return None; }
  688                      }
  689                  }
  690                  None => { return None; }
  691              }
  692              if end <= unit_len {
  693                  return Some(n);
  694              }
  695              end -= unit_len;
  696              // FIXME(#5992): assignment operator overloads
  697              // power *= base_num;
  698              power = power * base_num;
  699          }
  700      }
  701  
  702      #[inline]
  703      fn shl_unit(&self, n_unituint) -> BigUint {
  704          if n_unit == 0 || self.is_zero() { return (*self).clone(); }
  705  
  706          BigUint::new(Vec::from_elem(n_unit, ZERO_BIG_DIGIT).append(self.data.as_slice()))
  707      }
  708  
  709      #[inline]
  710      fn shl_bits(&self, n_bitsuint) -> BigUint {
  711          if n_bits == 0 || self.is_zero() { return (*self).clone(); }
  712  
  713          let mut carry = 0;
  714          let mut shiftedVec<BigDigit> = self.data.iter().map(|elem| {
  715              let (hi, lo) = BigDigit::from_doublebigdigit(
  716                  (*elem as DoubleBigDigit) << n_bits | (carry as DoubleBigDigit)
  717              );
  718              carry = hi;
  719              lo
  720          }).collect();
  721          if carry != 0 { shifted.push(carry); }
  722          return BigUint::new(shifted);
  723      }
  724  
  725      #[inline]
  726      fn shr_unit(&self, n_unituint) -> BigUint {
  727          if n_unit == 0 { return (*self).clone(); }
  728          if self.data.len() < n_unit { return Zero::zero(); }
  729          return BigUint::from_slice(
  730              self.data.slice(n_unit, self.data.len())
  731          );
  732      }
  733  
  734      #[inline]
  735      fn shr_bits(&self, n_bitsuint) -> BigUint {
  736          if n_bits == 0 || self.data.is_empty() { return (*self).clone(); }
  737  
  738          let mut borrow = 0;
  739          let mut shifted_rev = Vec::with_capacity(self.data.len());
  740          for elem in self.data.iter().rev() {
  741              shifted_rev.push((*elem >> n_bits) | borrow);
  742              borrow = *elem << (BigDigit::bits - n_bits);
  743          }
  744          let shifted = { shifted_rev.reverse(); shifted_rev };
  745          return BigUint::new(shifted);
  746      }
  747  
  748      /// Determines the fewest bits necessary to express the `BigUint`.
  749      pub fn bits(&self) -> uint {
  750          if self.is_zero() { return 0; }
  751          let zeros = self.data.last().unwrap().leading_zeros();
  752          return self.data.len()*BigDigit::bits - (zeros as uint);
  753      }
  754  }
  755  
  756  // `DoubleBigDigit` size dependent
  757  #[inline]
  758  fn get_radix_base(radix: uint) -> (DoubleBigDigit, uint) {
  759      assert!(1 < radix && radix <= 16);
  760      match radix {
  761          2  => (4294967296, 32),
  762          3  => (3486784401, 20),
  763          4  => (4294967296, 16),
  764          5  => (1220703125, 13),
  765          6  => (2176782336, 12),
  766          7  => (1977326743, 11),
  767          8  => (1073741824, 10),
  768          9  => (3486784401, 10),
  769          10 => (1000000000, 9),
  770          11 => (2357947691, 9),
  771          12 => (429981696,  8),
  772          13 => (815730721,  8),
  773          14 => (1475789056, 8),
  774          15 => (2562890625, 8),
  775          16 => (4294967296, 8),
  776          _  => fail!()
  777      }
  778  }
  779  
  780  /// A Sign is a `BigInt`'s composing element.
  781  #[deriving(Eq, Ord, TotalEq, TotalOrd, Clone, Show)]
  782  pub enum Sign { Minus, Zero, Plus }
  783  
  784  impl Neg<Sign> for Sign {
  785      /// Negate Sign value.
  786      #[inline]
  787      fn neg(&self) -> Sign {
  788          match *self {
  789            Minus => Plus,
  790            Zero  => Zero,
  791            Plus  => Minus
  792          }
  793      }
  794  }
  795  
  796  /// A big signed integer type.
  797  #[deriving(Clone)]
  798  pub struct BigInt {
  799      sign: Sign,
  800      data: BigUint
  801  }
  802  
  803  impl Eq for BigInt {
  804      #[inline]
  805      fn eq(&self, other&BigInt) -> bool {
  806          match self.cmp(other) { Equal => true, _ => false }
  807      }
  808  }
  809  
  810  impl TotalEq for BigInt {}
  811  
  812  impl Ord for BigInt {
  813      #[inline]
  814      fn lt(&self, other&BigInt) -> bool {
  815          match self.cmp(other) { Less => true, _ => false}
  816      }
  817  }
  818  
  819  impl TotalOrd for BigInt {
  820      #[inline]
  821      fn cmp(&self, other&BigInt) -> Ordering {
  822          let scmp = self.sign.cmp(&other.sign);
  823          if scmp != Equal { return scmp; }
  824  
  825          match self.sign {
  826              Zero  => Equal,
  827              Plus  => self.data.cmp(&other.data),
  828              Minus => other.data.cmp(&self.data),
  829          }
  830      }
  831  }
  832  
  833  impl fmt::Show for BigInt {
  834      fn fmt(&self, f&mut fmt::Formatter) -> fmt::Result {
  835          write!(f.buf, "{}", self.to_str_radix(10))
  836      }
  837  }
  838  
  839  impl FromStr for BigInt {
  840      #[inline]
  841      fn from_str(s&str) -> Option<BigInt> {
  842          FromStrRadix::from_str_radix(s, 10)
  843      }
  844  }
  845  
  846  impl Num for BigInt {}
  847  
  848  impl Shl<uint, BigInt> for BigInt {
  849      #[inline]
  850      fn shl(&self, rhs&uint) -> BigInt {
  851          BigInt::from_biguint(self.sign, self.data << *rhs)
  852      }
  853  }
  854  
  855  impl Shr<uint, BigInt> for BigInt {
  856      #[inline]
  857      fn shr(&self, rhs&uint) -> BigInt {
  858          BigInt::from_biguint(self.sign, self.data >> *rhs)
  859      }
  860  }
  861  
  862  impl Zero for BigInt {
  863      #[inline]
  864      fn zero() -> BigInt {
  865          BigInt::from_biguint(Zero, Zero::zero())
  866      }
  867  
  868      #[inline]
  869      fn is_zero(&self) -> bool { self.sign == Zero }
  870  }
  871  
  872  impl One for BigInt {
  873      #[inline]
  874      fn one() -> BigInt {
  875          BigInt::from_biguint(Plus, One::one())
  876      }
  877  }
  878  
  879  impl Signed for BigInt {
  880      #[inline]
  881      fn abs(&self) -> BigInt {
  882          match self.sign {
  883              Plus | Zero => self.clone(),
  884              Minus => BigInt::from_biguint(Plus, self.data.clone())
  885          }
  886      }
  887  
  888      #[inline]
  889      fn abs_sub(&self, other&BigInt) -> BigInt {
  890          if *self <= *other { Zero::zero() } else { *self - *other }
  891      }
  892  
  893      #[inline]
  894      fn signum(&self) -> BigInt {
  895          match self.sign {
  896              Plus  => BigInt::from_biguint(Plus, One::one()),
  897              Minus => BigInt::from_biguint(Minus, One::one()),
  898              Zero  => Zero::zero(),
  899          }
  900      }
  901  
  902      #[inline]
  903      fn is_positive(&self) -> bool { self.sign == Plus }
  904  
  905      #[inline]
  906      fn is_negative(&self) -> bool { self.sign == Minus }
  907  }
  908  
  909  impl Add<BigInt, BigInt> for BigInt {
  910      #[inline]
  911      fn add(&self, other&BigInt) -> BigInt {
  912          match (self.sign, other.sign) {
  913              (Zero, _)      => other.clone(),
  914              (_,    Zero)   => self.clone(),
  915              (Plus, Plus)   => BigInt::from_biguint(Plus,
  916                                                     self.data + other.data),
  917              (Plus, Minus)  => self - (-*other),
  918              (Minus, Plus)  => other - (-*self),
  919              (Minus, Minus) => -((-self) + (-*other))
  920          }
  921      }
  922  }
  923  
  924  impl Sub<BigInt, BigInt> for BigInt {
  925      #[inline]
  926      fn sub(&self, other&BigInt) -> BigInt {
  927          match (self.sign, other.sign) {
  928              (Zero, _)    => -other,
  929              (_,    Zero) => self.clone(),
  930              (Plus, Plus) => match self.data.cmp(&other.data) {
  931                  Less    => BigInt::from_biguint(Minus, other.data - self.data),
  932                  Greater => BigInt::from_biguint(Plus, self.data - other.data),
  933                  Equal   => Zero::zero()
  934              },
  935              (Plus, Minus) => self + (-*other),
  936              (Minus, Plus) => -((-self) + *other),
  937              (Minus, Minus) => (-other) - (-*self)
  938          }
  939      }
  940  }
  941  
  942  impl Mul<BigInt, BigInt> for BigInt {
  943      #[inline]
  944      fn mul(&self, other&BigInt) -> BigInt {
  945          match (self.sign, other.sign) {
  946              (Zero, _)     | (_,     Zero)  => Zero::zero(),
  947              (Plus, Plus)  | (Minus, Minus) => {
  948                  BigInt::from_biguint(Plus, self.data * other.data)
  949              },
  950              (Plus, Minus) | (Minus, Plus) => {
  951                  BigInt::from_biguint(Minus, self.data * other.data)
  952              }
  953          }
  954      }
  955  }
  956  
  957  impl Div<BigInt, BigInt> for BigInt {
  958      #[inline]
  959      fn div(&self, other&BigInt) -> BigInt {
  960          let (q, _) = self.div_rem(other);
  961          return q;
  962      }
  963  }
  964  
  965  impl Rem<BigInt, BigInt> for BigInt {
  966      #[inline]
  967      fn rem(&self, other&BigInt) -> BigInt {
  968          let (_, r) = self.div_rem(other);
  969          return r;
  970      }
  971  }
  972  
  973  impl Neg<BigInt> for BigInt {
  974      #[inline]
  975      fn neg(&self) -> BigInt {
  976          BigInt::from_biguint(self.sign.neg(), self.data.clone())
  977      }
  978  }
  979  
  980  impl CheckedAdd for BigInt {
  981      #[inline]
  982      fn checked_add(&self, v&BigInt) -> Option<BigInt> {
  983          return Some(self.add(v));
  984      }
  985  }
  986  
  987  impl CheckedSub for BigInt {
  988      #[inline]
  989      fn checked_sub(&self, v&BigInt) -> Option<BigInt> {
  990          return Some(self.sub(v));
  991      }
  992  }
  993  
  994  impl CheckedMul for BigInt {
  995      #[inline]
  996      fn checked_mul(&self, v&BigInt) -> Option<BigInt> {
  997          return Some(self.mul(v));
  998      }
  999  }
 1000  
 1001  impl CheckedDiv for BigInt {
 1002      #[inline]
 1003      fn checked_div(&self, v&BigInt) -> Option<BigInt> {
 1004          if v.is_zero() {
 1005              return None;
 1006          }
 1007          return Some(self.div(v));
 1008      }
 1009  }
 1010  
 1011  
 1012  impl Integer for BigInt {
 1013      #[inline]
 1014      fn div_rem(&self, other&BigInt) -> (BigInt, BigInt) {
 1015          // r.sign == self.sign
 1016          let (d_ui, r_ui) = self.data.div_mod_floor(&other.data);
 1017          let d = BigInt::from_biguint(Plus, d_ui);
 1018          let r = BigInt::from_biguint(Plus, r_ui);
 1019          match (self.sign, other.sign) {
 1020              (_,    Zero)   => fail!(),
 1021              (Plus, Plus)  | (Zero, Plus)  => ( d,  r),
 1022              (Plus, Minus) | (Zero, Minus) => (-d,  r),
 1023              (Minus, Plus)                 => (-d, -r),
 1024              (Minus, Minus)                => ( d, -r)
 1025          }
 1026      }
 1027  
 1028      #[inline]
 1029      fn div_floor(&self, other&BigInt) -> BigInt {
 1030          let (d, _) = self.div_mod_floor(other);
 1031          return d;
 1032      }
 1033  
 1034      #[inline]
 1035      fn mod_floor(&self, other&BigInt) -> BigInt {
 1036          let (_, m) = self.div_mod_floor(other);
 1037          return m;
 1038      }
 1039  
 1040      fn div_mod_floor(&self, other&BigInt) -> (BigInt, BigInt) {
 1041          // m.sign == other.sign
 1042          let (d_ui, m_ui) = self.data.div_rem(&other.data);
 1043          let d = BigInt::from_biguint(Plus, d_ui);
 1044          let m = BigInt::from_biguint(Plus, m_ui);
 1045          match (self.sign, other.sign) {
 1046              (_,    Zero)   => fail!(),
 1047              (Plus, Plus)  | (Zero, Plus)  => (d, m),
 1048              (Plus, Minus) | (Zero, Minus) => if m.is_zero() {
 1049                  (-d, Zero::zero())
 1050              } else {
 1051                  (-d - One::one(), m + *other)
 1052              },
 1053              (Minus, Plus) => if m.is_zero() {
 1054                  (-d, Zero::zero())
 1055              } else {
 1056                  (-d - One::one(), other - m)
 1057              },
 1058              (Minus, Minus) => (d, -m)
 1059          }
 1060      }
 1061  
 1062      /**
 1063       * Calculates the Greatest Common Divisor (GCD) of the number and `other`
 1064       *
 1065       * The result is always positive
 1066       */
 1067      #[inline]
 1068      fn gcd(&self, other&BigInt) -> BigInt {
 1069          BigInt::from_biguint(Plus, self.data.gcd(&other.data))
 1070      }
 1071  
 1072      /**
 1073       * Calculates the Lowest Common Multiple (LCM) of the number and `other`
 1074       */
 1075      #[inline]
 1076      fn lcm(&self, other&BigInt) -> BigInt {
 1077          BigInt::from_biguint(Plus, self.data.lcm(&other.data))
 1078      }
 1079  
 1080      /// Returns `true` if the number can be divided by `other` without leaving a remainder
 1081      #[inline]
 1082      fn divides(&self, other&BigInt) -> bool { self.data.divides(&other.data) }
 1083  
 1084      /// Returns `true` if the number is divisible by `2`
 1085      #[inline]
 1086      fn is_even(&self) -> bool { self.data.is_even() }
 1087  
 1088      /// Returns `true` if the number is not divisible by `2`
 1089      #[inline]
 1090      fn is_odd(&self) -> bool { self.data.is_odd() }
 1091  }
 1092  
 1093  impl ToPrimitive for BigInt {
 1094      #[inline]
 1095      fn to_i64(&self) -> Option<i64> {
 1096          match self.sign {
 1097              Plus  => self.data.to_i64(),
 1098              Zero  => Some(0),
 1099              Minus => {
 1100                  self.data.to_u64().and_then(|n| {
 1101                      let mu64 = 1 << 63;
 1102                      if n < m {
 1103                          Some(-(n as i64))
 1104                      } else if n == m {
 1105                          Some(i64::MIN)
 1106                      } else {
 1107                          None
 1108                      }
 1109                  })
 1110              }
 1111          }
 1112      }
 1113  
 1114      #[inline]
 1115      fn to_u64(&self) -> Option<u64> {
 1116          match self.sign {
 1117              Plus => self.data.to_u64(),
 1118              Zero => Some(0),
 1119              Minus => None
 1120          }
 1121      }
 1122  }
 1123  
 1124  impl FromPrimitive for BigInt {
 1125      #[inline]
 1126      fn from_i64(ni64) -> Option<BigInt> {
 1127          if n > 0 {
 1128              FromPrimitive::from_u64(n as u64).and_then(|n| {
 1129                  Some(BigInt::from_biguint(Plus, n))
 1130              })
 1131          } else if n < 0 {
 1132              FromPrimitive::from_u64(u64::MAX - (n as u64) + 1).and_then(
 1133                  |n| {
 1134                      Some(BigInt::from_biguint(Minus, n))
 1135                  })
 1136          } else {
 1137              Some(Zero::zero())
 1138          }
 1139      }
 1140  
 1141      #[inline]
 1142      fn from_u64(nu64) -> Option<BigInt> {
 1143          if n == 0 {
 1144              Some(Zero::zero())
 1145          } else {
 1146              FromPrimitive::from_u64(n).and_then(|n| {
 1147                  Some(BigInt::from_biguint(Plus, n))
 1148              })
 1149          }
 1150      }
 1151  }
 1152  
 1153  /// A generic trait for converting a value to a `BigInt`.
 1154  pub trait ToBigInt {
 1155      /// Converts the value of `self` to a `BigInt`.
 1156      fn to_bigint(&self) -> Option<BigInt>;
 1157  }
 1158  
 1159  impl ToBigInt for BigInt {
 1160      #[inline]
 1161      fn to_bigint(&self) -> Option<BigInt> {
 1162          Some(self.clone())
 1163      }
 1164  }
 1165  
 1166  impl ToBigInt for BigUint {
 1167      #[inline]
 1168      fn to_bigint(&self) -> Option<BigInt> {
 1169          if self.is_zero() {
 1170              Some(Zero::zero())
 1171          } else {
 1172              Some(BigInt { sign: Plus, data: self.clone() })
 1173          }
 1174      }
 1175  }
 1176  
 1177  macro_rules! impl_to_bigint(
 1178      ($T:ty, $from_ty:path) => {
 1179          impl ToBigInt for $T {
 1180              #[inline]
 1181              fn to_bigint(&self) -> Option<BigInt> {
 1182                  $from_ty(*self)
 1183              }
 1184          }
 1185      }
 1186  )
 1187  
 1188  impl_to_bigint!(int,  FromPrimitive::from_int)
 1189  impl_to_bigint!(i8,   FromPrimitive::from_i8)
 1190  impl_to_bigint!(i16,  FromPrimitive::from_i16)
 1191  impl_to_bigint!(i32,  FromPrimitive::from_i32)
 1192  impl_to_bigint!(i64,  FromPrimitive::from_i64)
 1193  impl_to_bigint!(uint, FromPrimitive::from_uint)
 1194  impl_to_bigint!(u8,   FromPrimitive::from_u8)
 1195  impl_to_bigint!(u16,  FromPrimitive::from_u16)
 1196  impl_to_bigint!(u32,  FromPrimitive::from_u32)
 1197  impl_to_bigint!(u64,  FromPrimitive::from_u64)
 1198  
 1199  impl ToStrRadix for BigInt {
 1200      #[inline]
 1201      fn to_str_radix(&self, radixuint) -> ~str {
 1202          match self.sign {
 1203              Plus  => self.data.to_str_radix(radix),
 1204              Zero  => "0".to_owned(),
 1205              Minus => "-".to_owned() + self.data.to_str_radix(radix)
 1206          }
 1207      }
 1208  }
 1209  
 1210  impl FromStrRadix for BigInt {
 1211      /// Creates and initializes a BigInt.
 1212      #[inline]
 1213      fn from_str_radix(s&str, radixuint) -> Option<BigInt> {
 1214          BigInt::parse_bytes(s.as_bytes(), radix)
 1215      }
 1216  }
 1217  
 1218  pub trait RandBigInt {
 1219      /// Generate a random `BigUint` of the given bit size.
 1220      fn gen_biguint(&mut self, bit_size: uint) -> BigUint;
 1221  
 1222      /// Generate a random BigInt of the given bit size.
 1223      fn gen_bigint(&mut self, bit_size: uint) -> BigInt;
 1224  
 1225      /// Generate a random `BigUint` less than the given bound. Fails
 1226      /// when the bound is zero.
 1227      fn gen_biguint_below(&mut self, bound: &BigUint) -> BigUint;
 1228  
 1229      /// Generate a random `BigUint` within the given range. The lower
 1230      /// bound is inclusive; the upper bound is exclusive. Fails when
 1231      /// the upper bound is not greater than the lower bound.
 1232      fn gen_biguint_range(&mut self, lbound: &BigUint, ubound: &BigUint) -> BigUint;
 1233  
 1234      /// Generate a random `BigInt` within the given range. The lower
 1235      /// bound is inclusive; the upper bound is exclusive. Fails when
 1236      /// the upper bound is not greater than the lower bound.
 1237      fn gen_bigint_range(&mut self, lbound: &BigInt, ubound: &BigInt) -> BigInt;
 1238  }
 1239  
 1240  impl<R: Rng> RandBigInt for R {
 1241      fn gen_biguint(&mut self, bit_sizeuint) -> BigUint {
 1242          let (digits, rem) = bit_size.div_rem(&BigDigit::bits);
 1243          let mut data = Vec::with_capacity(digits+1);
 1244          for _ in range(0, digits) {
 1245              data.push(self.gen());
 1246          }
 1247          if rem > 0 {
 1248              let final_digitBigDigit = self.gen();
 1249              data.push(final_digit >> (BigDigit::bits - rem));
 1250          }
 1251          return BigUint::new(data);
 1252      }
 1253  
 1254      fn gen_bigint(&mut self, bit_sizeuint) -> BigInt {
 1255          // Generate a random BigUint...
 1256          let biguint = self.gen_biguint(bit_size);
 1257          // ...and then randomly assign it a Sign...
 1258          let sign = if biguint.is_zero() {
 1259              // ...except that if the BigUint is zero, we need to try
 1260              // again with probability 0.5. This is because otherwise,
 1261              // the probability of generating a zero BigInt would be
 1262              // double that of any other number.
 1263              if self.gen() {
 1264                  return self.gen_bigint(bit_size);
 1265              } else {
 1266                  Zero
 1267              }
 1268          } else if self.gen() {
 1269              Plus
 1270          } else {
 1271              Minus
 1272          };
 1273          return BigInt::from_biguint(sign, biguint);
 1274      }
 1275  
 1276      fn gen_biguint_below(&mut self, bound&BigUint) -> BigUint {
 1277          assert!(!bound.is_zero());
 1278          let bits = bound.bits();
 1279          loop {
 1280              let n = self.gen_biguint(bits);
 1281              if n < *bound { return n; }
 1282          }
 1283      }
 1284  
 1285      fn gen_biguint_range(&mut self,
 1286                           lbound&BigUint,
 1287                           ubound&BigUint)
 1288                           -> BigUint {
 1289          assert!(*lbound < *ubound);
 1290          return *lbound + self.gen_biguint_below(&(*ubound - *lbound));
 1291      }
 1292  
 1293      fn gen_bigint_range(&mut self,
 1294                          lbound&BigInt,
 1295                          ubound&BigInt)
 1296                          -> BigInt {
 1297          assert!(*lbound < *ubound);
 1298          let delta = (*ubound - *lbound).to_biguint().unwrap();
 1299          return *lbound + self.gen_biguint_below(&delta).to_bigint().unwrap();
 1300      }
 1301  }
 1302  
 1303  impl BigInt {
 1304      /// Creates and initializes a BigInt.
 1305      #[inline]
 1306      pub fn new(signSign, vVec<BigDigit>) -> BigInt {
 1307          BigInt::from_biguint(sign, BigUint::new(v))
 1308      }
 1309  
 1310      /// Creates and initializes a `BigInt`.
 1311      #[inline]
 1312      pub fn from_biguint(signSign, dataBigUint) -> BigInt {
 1313          if sign == Zero || data.is_zero() {
 1314              return BigInt { sign: Zero, data: Zero::zero() };
 1315          }
 1316          return BigInt { sign: sign, data: data };
 1317      }
 1318  
 1319      /// Creates and initializes a `BigInt`.
 1320      #[inline]
 1321      pub fn from_slice(signSign, slice&[BigDigit]) -> BigInt {
 1322          BigInt::from_biguint(sign, BigUint::from_slice(slice))
 1323      }
 1324  
 1325      /// Creates and initializes a `BigInt`.
 1326      pub fn parse_bytes(buf&[u8], radixuint)
 1327          -> Option<BigInt> {
 1328          if buf.is_empty() { return None; }
 1329          let mut sign  = Plus;
 1330          let mut start = 0;
 1331          if buf[0] == ('-' as u8) {
 1332              sign  = Minus;
 1333              start = 1;
 1334          }
 1335          return BigUint::parse_bytes(buf.slice(start, buf.len()), radix)
 1336              .map(|bu| BigInt::from_biguint(sign, bu));
 1337      }
 1338  
 1339      /// Converts this `BigInt` into a `BigUint`, if it's not negative.
 1340      #[inline]
 1341      pub fn to_biguint(&self) -> Option<BigUint> {
 1342          match self.sign {
 1343              Plus => Some(self.data.clone()),
 1344              Zero => Some(Zero::zero()),
 1345              Minus => None
 1346          }
 1347      }
 1348  }
 1349  
 1350  #[cfg(test)]
 1351  mod biguint_tests {
 1352      use Integer;
 1353      use super::{BigDigit, BigUint, ToBigUint};
 1354      use super::{Plus, BigInt, RandBigInt, ToBigInt};
 1355  
 1356      use std::cmp::{Less, Equal, Greater};
 1357      use std::from_str::FromStr;
 1358      use std::i64;
 1359      use std::num::{Zero, One, FromStrRadix, ToStrRadix};
 1360      use std::num::{ToPrimitive, FromPrimitive};
 1361      use std::num::CheckedDiv;
 1362      use rand::{task_rng};
 1363      use std::u64;
 1364  
 1365      #[test]
 1366      fn test_from_slice() {
 1367          fn check(slice: &[BigDigit], data: &[BigDigit]) {
 1368              assert!(data == BigUint::from_slice(slice).data.as_slice());
 1369          }
 1370          check([1], [1]);
 1371          check([0, 0, 0], []);
 1372          check([1, 2, 0, 0], [1, 2]);
 1373          check([0, 0, 1, 2], [0, 0, 1, 2]);
 1374          check([0, 0, 1, 2, 0, 0], [0, 0, 1, 2]);
 1375          check([-1], [-1]);
 1376      }
 1377  
 1378      #[test]
 1379      fn test_cmp() {
 1380          let data: Vec<BigUint> = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1]  ]
 1381              .iter().map(|v| BigUint::from_slice(*v)).collect();
 1382          for (i, ni) in data.iter().enumerate() {
 1383              for (j0, nj) in data.slice(i, data.len()).iter().enumerate() {
 1384                  let j = j0 + i;
 1385                  if i == j {
 1386                      assert_eq!(ni.cmp(nj), Equal);
 1387                      assert_eq!(nj.cmp(ni), Equal);
 1388                      assert_eq!(ni, nj);
 1389                      assert!(!(ni != nj));
 1390                      assert!(ni <= nj);
 1391                      assert!(ni >= nj);
 1392                      assert!(!(ni < nj));
 1393                      assert!(!(ni > nj));
 1394                  } else {
 1395                      assert_eq!(ni.cmp(nj), Less);
 1396                      assert_eq!(nj.cmp(ni), Greater);
 1397  
 1398                      assert!(!(ni == nj));
 1399                      assert!(ni != nj);
 1400  
 1401                      assert!(ni <= nj);
 1402                      assert!(!(ni >= nj));
 1403                      assert!(ni < nj);
 1404                      assert!(!(ni > nj));
 1405  
 1406                      assert!(!(nj <= ni));
 1407                      assert!(nj >= ni);
 1408                      assert!(!(nj < ni));
 1409                      assert!(nj > ni);
 1410                  }
 1411              }
 1412          }
 1413      }
 1414  
 1415      #[test]
 1416      fn test_bitand() {
 1417          fn check(left: &[BigDigit],
 1418                   right: &[BigDigit],
 1419                   expected: &[BigDigit]) {
 1420              assert_eq!(BigUint::from_slice(left) & BigUint::from_slice(right),
 1421                         BigUint::from_slice(expected));
 1422          }
 1423          check([], [], []);
 1424          check([268, 482, 17],
 1425                [964, 54],
 1426                [260, 34]);
 1427      }
 1428  
 1429      #[test]
 1430      fn test_bitor() {
 1431          fn check(left: &[BigDigit],
 1432                   right: &[BigDigit],
 1433                   expected: &[BigDigit]) {
 1434              assert_eq!(BigUint::from_slice(left) | BigUint::from_slice(right),
 1435                         BigUint::from_slice(expected));
 1436          }
 1437          check([], [], []);
 1438          check([268, 482, 17],
 1439                [964, 54],
 1440                [972, 502, 17]);
 1441      }
 1442  
 1443      #[test]
 1444      fn test_bitxor() {
 1445          fn check(left: &[BigDigit],
 1446                   right: &[BigDigit],
 1447                   expected: &[BigDigit]) {
 1448              assert_eq!(BigUint::from_slice(left) ^ BigUint::from_slice(right),
 1449                         BigUint::from_slice(expected));
 1450          }
 1451          check([], [], []);
 1452          check([268, 482, 17],
 1453                [964, 54],
 1454                [712, 468, 17]);
 1455      }
 1456  
 1457      #[test]
 1458      fn test_shl() {
 1459          fn check(s: &str, shift: uint, ans: &str) {
 1460              let opt_biguint: Option<BigUint> = FromStrRadix::from_str_radix(s, 16);
 1461              let bu = (opt_biguint.unwrap() << shift).to_str_radix(16);
 1462              assert_eq!(bu.as_slice(), ans);
 1463          }
 1464  
 1465          check("0", 3, "0");
 1466          check("1", 3, "8");
 1467  
 1468          check("1" + "0000" + "0000" + "0000" + "0001" + "0000" + "0000" + "0000" + "0001", 3,
 1469                "8" + "0000" + "0000" + "0000" + "0008" + "0000" + "0000" + "0000" + "0008");
 1470          check("1" + "0000" + "0001" + "0000" + "0001", 2,
 1471                "4" + "0000" + "0004" + "0000" + "0004");
 1472          check("1" + "0001" + "0001", 1,
 1473                "2" + "0002" + "0002");
 1474  
 1475          check(""  + "4000" + "0000" + "0000" + "0000", 3,
 1476                "2" + "0000" + "0000" + "0000" + "0000");
 1477          check(""  + "4000" + "0000", 2,
 1478                "1" + "0000" + "0000");
 1479          check(""  + "4000", 2,
 1480                "1" + "0000");
 1481  
 1482          check(""  + "4000" + "0000" + "0000" + "0000", 67,
 1483                "2" + "0000" + "0000" + "0000" + "0000" + "0000" + "0000" + "0000" + "0000");
 1484          check(""  + "4000" + "0000", 35,
 1485                "2" + "0000" + "0000" + "0000" + "0000");
 1486          check(""  + "4000", 19,
 1487                "2" + "0000" + "0000");
 1488  
 1489          check(""  + "fedc" + "ba98" + "7654" + "3210" + "fedc" + "ba98" + "7654" + "3210", 4,
 1490                "f" + "edcb" + "a987" + "6543" + "210f" + "edcb" + "a987" + "6543" + "2100");
 1491          check("88887777666655554444333322221111", 16,
 1492                "888877776666555544443333222211110000");
 1493      }
 1494  
 1495      #[test]
 1496      fn test_shr() {
 1497          fn check(s: &str, shift: uint, ans: &str) {
 1498              let opt_biguint: Option<BigUint> =
 1499                  FromStrRadix::from_str_radix(s, 16);
 1500              let bu = (opt_biguint.unwrap() >> shift).to_str_radix(16);
 1501              assert_eq!(bu.as_slice(), ans);
 1502          }
 1503  
 1504          check("0", 3, "0");
 1505          check("f", 3, "1");
 1506  
 1507          check("1" + "0000" + "0000" + "0000" + "0001" + "0000" + "0000" + "0000" + "0001", 3,
 1508                ""  + "2000" + "0000" + "0000" + "0000" + "2000" + "0000" + "0000" + "0000");
 1509          check("1" + "0000" + "0001" + "0000" + "0001", 2,
 1510                ""  + "4000" + "0000" + "4000" + "0000");
 1511          check("1" + "0001" + "0001", 1,
 1512                ""  + "8000" + "8000");
 1513  
 1514          check("2" + "0000" + "0000" + "0000" + "0001" + "0000" + "0000" + "0000" + "0001", 67,
 1515                ""  + "4000" + "0000" + "0000" + "0000");
 1516          check("2" + "0000" + "0001" + "0000" + "0001", 35,
 1517                ""  + "4000" + "0000");
 1518          check("2" + "0001" + "0001", 19,
 1519                ""  + "4000");
 1520  
 1521          check("1" + "0000" + "0000" + "0000" + "0000", 1,
 1522                ""  + "8000" + "0000" + "0000" + "0000");
 1523          check("1" + "0000" + "0000", 1,
 1524                ""  + "8000" + "0000");
 1525          check("1" + "0000", 1,
 1526                ""  + "8000");
 1527          check("f" + "edcb" + "a987" + "6543" + "210f" + "edcb" + "a987" + "6543" + "2100", 4,
 1528                ""  + "fedc" + "ba98" + "7654" + "3210" + "fedc" + "ba98" + "7654" + "3210");
 1529  
 1530          check("888877776666555544443333222211110000", 16,
 1531                "88887777666655554444333322221111");
 1532      }
 1533  
 1534      // `DoubleBigDigit` size dependent
 1535      #[test]
 1536      fn test_convert_i64() {
 1537          fn check(b1: BigUint, i: i64) {
 1538              let b2: BigUint = FromPrimitive::from_i64(i).unwrap();
 1539              assert!(b1 == b2);
 1540              assert!(b1.to_i64().unwrap() == i);
 1541          }
 1542  
 1543          check(Zero::zero(), 0);
 1544          check(One::one(), 1);
 1545          check(i64::MAX.to_biguint().unwrap(), i64::MAX);
 1546  
 1547          check(BigUint::new(vec!(           )), 0);
 1548          check(BigUint::new(vec!( 1         )), (1 << (0*BigDigit::bits)));
 1549          check(BigUint::new(vec!(-1         )), (1 << (1*BigDigit::bits)) - 1);
 1550          check(BigUint::new(vec!( 0,  1     )), (1 << (1*BigDigit::bits)));
 1551          check(BigUint::new(vec!(-1, -1 >> 1)), i64::MAX);
 1552  
 1553          assert_eq!(i64::MIN.to_biguint(), None);
 1554          assert_eq!(BigUint::new(vec!(-1, -1    )).to_i64(), None);
 1555          assert_eq!(BigUint::new(vec!( 0,  0,  1)).to_i64(), None);
 1556          assert_eq!(BigUint::new(vec!(-1, -1, -1)).to_i64(), None);
 1557      }
 1558  
 1559      // `DoubleBigDigit` size dependent
 1560      #[test]
 1561      fn test_convert_u64() {
 1562          fn check(b1: BigUint, u: u64) {
 1563              let b2: BigUint = FromPrimitive::from_u64(u).unwrap();
 1564              assert!(b1 == b2);
 1565              assert!(b1.to_u64().unwrap() == u);
 1566          }
 1567  
 1568          check(Zero::zero(), 0);
 1569          check(One::one(), 1);
 1570          check(u64::MIN.to_biguint().unwrap(), u64::MIN);
 1571          check(u64::MAX.to_biguint().unwrap(), u64::MAX);
 1572  
 1573          check(BigUint::new(vec!(      )), 0);
 1574          check(BigUint::new(vec!( 1    )), (1 << (0*BigDigit::bits)));
 1575          check(BigUint::new(vec!(-1    )), (1 << (1*BigDigit::bits)) - 1);
 1576          check(BigUint::new(vec!( 0,  1)), (1 << (1*BigDigit::bits)));
 1577          check(BigUint::new(vec!(-1, -1)), u64::MAX);
 1578  
 1579          assert_eq!(BigUint::new(vec!( 0,  0,  1)).to_u64(), None);
 1580          assert_eq!(BigUint::new(vec!(-1, -1, -1)).to_u64(), None);
 1581      }
 1582  
 1583      #[test]
 1584      fn test_convert_to_bigint() {
 1585          fn check(n: BigUint, ans: BigInt) {
 1586              assert_eq!(n.to_bigint().unwrap(), ans);
 1587              assert_eq!(n.to_bigint().unwrap().to_biguint().unwrap(), n);
 1588          }
 1589          check(Zero::zero(), Zero::zero());
 1590          check(BigUint::new(vec!(1,2,3)),
 1591                BigInt::from_biguint(Plus, BigUint::new(vec!(1,2,3))));
 1592      }
 1593  
 1594      static sum_triples: &'static [(&'static [BigDigit],
 1595                                     &'static [BigDigit],
 1596                                     &'static [BigDigit])] = &[
 1597          (&[],          &[],       &[]),
 1598          (&[],          &[ 1],     &[ 1]),
 1599          (&[ 1],        &[ 1],     &[ 2]),
 1600          (&[ 1],        &[ 1,  1], &[ 2,  1]),
 1601          (&[ 1],        &[-1],     &[ 0,  1]),
 1602          (&[ 1],        &[-1, -1], &[ 0,  0, 1]),
 1603          (&[-1, -1],    &[-1, -1], &[-2, -1, 1]),
 1604          (&[ 1,  1, 1], &[-1, -1], &[ 0,  1, 2]),
 1605          (&[ 2,  2, 1], &[-1, -2], &[ 1,  1, 2])
 1606      ];
 1607  
 1608      #[test]
 1609      fn test_add() {
 1610          for elm in sum_triples.iter() {
 1611              let (a_vec, b_vec, c_vec) = *elm;
 1612              let a = BigUint::from_slice(a_vec);
 1613              let b = BigUint::from_slice(b_vec);
 1614              let c = BigUint::from_slice(c_vec);
 1615  
 1616              assert!(a + b == c);
 1617              assert!(b + a == c);
 1618          }
 1619      }
 1620  
 1621      #[test]
 1622      fn test_sub() {
 1623          for elm in sum_triples.iter() {
 1624              let (a_vec, b_vec, c_vec) = *elm;
 1625              let a = BigUint::from_slice(a_vec);
 1626              let b = BigUint::from_slice(b_vec);
 1627              let c = BigUint::from_slice(c_vec);
 1628  
 1629              assert!(c - a == b);
 1630              assert!(c - b == a);
 1631          }
 1632      }
 1633  
 1634      #[test]
 1635      #[should_fail]
 1636      fn test_sub_fail_on_underflow() {
 1637          let (a, b) : (BigUint, BigUint) = (Zero::zero(), One::one());
 1638          a - b;
 1639      }
 1640  
 1641      static mul_triples: &'static [(&'static [BigDigit],
 1642                                     &'static [BigDigit],
 1643                                     &'static [BigDigit])] = &[
 1644          (&[],               &[],               &[]),
 1645          (&[],               &[ 1],             &[]),
 1646          (&[ 2],             &[],               &[]),
 1647          (&[ 1],             &[ 1],             &[1]),
 1648          (&[ 2],             &[ 3],             &[ 6]),
 1649          (&[ 1],             &[ 1,  1,  1],     &[1, 1,  1]),
 1650          (&[ 1,  2,  3],     &[ 3],             &[ 3,  6,  9]),
 1651          (&[ 1,  1,  1],     &[-1],             &[-1, -1, -1]),
 1652          (&[ 1,  2,  3],     &[-1],             &[-1, -2, -2, 2]),
 1653          (&[ 1,  2,  3,  4], &[-1],             &[-1, -2, -2, -2, 3]),
 1654          (&[-1],             &[-1],             &[ 1, -2]),
 1655          (&[-1, -1],         &[-1],             &[ 1, -1, -2]),
 1656          (&[-1, -1, -1],     &[-1],             &[ 1, -1, -1, -2]),
 1657          (&[-1, -1, -1, -1], &[-1],             &[ 1, -1, -1, -1, -2]),
 1658          (&[-1/2 + 1],       &[ 2],             &[ 0,  1]),
 1659          (&[0, -1/2 + 1],    &[ 2],             &[ 0,  0,  1]),
 1660          (&[ 1,  2],         &[ 1,  2,  3],     &[1, 4,  7,  6]),
 1661          (&[-1, -1],         &[-1, -1, -1],     &[1, 0, -1, -2, -1]),
 1662          (&[-1, -1, -1],     &[-1, -1, -1, -1], &[1, 0,  0, -1, -2, -1, -1]),
 1663          (&[ 0,  0,  1],     &[ 1,  2,  3],     &[0, 0,  1,  2,  3]),
 1664          (&[ 0,  0,  1],     &[ 0,  0,  0,  1], &[0, 0,  0,  0,  0,  1])
 1665      ];
 1666  
 1667      static div_rem_quadruples: &'static [(&'static [BigDigit],
 1668                                             &'static [BigDigit],
 1669                                             &'static [BigDigit],
 1670                                             &'static [BigDigit])]
 1671          = &[
 1672              (&[ 1],        &[ 2], &[],               &[1]),
 1673              (&[ 1,  1],    &[ 2], &[-1/2+1],         &[1]),
 1674              (&[ 1,  1, 1], &[ 2], &[-1/2+1, -1/2+1], &[1]),
 1675              (&[ 0,  1],    &[-1], &[1],              &[1]),
 1676              (&[-1, -1],    &[-2], &[2, 1],           &[3])
 1677          ];
 1678  
 1679      #[test]
 1680      fn test_mul() {
 1681          for elm in mul_triples.iter() {
 1682              let (a_vec, b_vec, c_vec) = *elm;
 1683              let a = BigUint::from_slice(a_vec);
 1684              let b = BigUint::from_slice(b_vec);
 1685              let c = BigUint::from_slice(c_vec);
 1686  
 1687              assert!(a * b == c);
 1688              assert!(b * a == c);
 1689          }
 1690  
 1691          for elm in div_rem_quadruples.iter() {
 1692              let (a_vec, b_vec, c_vec, d_vec) = *elm;
 1693              let a = BigUint::from_slice(a_vec);
 1694              let b = BigUint::from_slice(b_vec);
 1695              let c = BigUint::from_slice(c_vec);
 1696              let d = BigUint::from_slice(d_vec);
 1697  
 1698              assert!(a == b * c + d);
 1699              assert!(a == c * b + d);
 1700          }
 1701      }
 1702  
 1703      #[test]
 1704      fn test_div_rem() {
 1705          for elm in mul_triples.iter() {
 1706              let (a_vec, b_vec, c_vec) = *elm;
 1707              let a = BigUint::from_slice(a_vec);
 1708              let b = BigUint::from_slice(b_vec);
 1709              let c = BigUint::from_slice(c_vec);
 1710  
 1711              if !a.is_zero() {
 1712                  assert_eq!(c.div_rem(&a), (b.clone(), Zero::zero()));
 1713              }
 1714              if !b.is_zero() {
 1715                  assert_eq!(c.div_rem(&b), (a.clone(), Zero::zero()));
 1716              }
 1717          }
 1718  
 1719          for elm in div_rem_quadruples.iter() {
 1720              let (a_vec, b_vec, c_vec, d_vec) = *elm;
 1721              let a = BigUint::from_slice(a_vec);
 1722              let b = BigUint::from_slice(b_vec);
 1723              let c = BigUint::from_slice(c_vec);
 1724              let d = BigUint::from_slice(d_vec);
 1725  
 1726              if !b.is_zero() { assert!(a.div_rem(&b) == (c, d)); }
 1727          }
 1728      }
 1729  
 1730      #[test]
 1731      fn test_checked_add() {
 1732          for elm in sum_triples.iter() {
 1733              let (aVec, bVec, cVec) = *elm;
 1734              let a = BigUint::from_slice(aVec);
 1735              let b = BigUint::from_slice(bVec);
 1736              let c = BigUint::from_slice(cVec);
 1737  
 1738              assert!(a.checked_add(&b).unwrap() == c);
 1739              assert!(b.checked_add(&a).unwrap() == c);
 1740          }
 1741      }
 1742  
 1743      #[test]
 1744      fn test_checked_sub() {
 1745          for elm in sum_triples.iter() {
 1746              let (aVec, bVec, cVec) = *elm;
 1747              let a = BigUint::from_slice(aVec);
 1748              let b = BigUint::from_slice(bVec);
 1749              let c = BigUint::from_slice(cVec);
 1750  
 1751              assert!(c.checked_sub(&a).unwrap() == b);
 1752              assert!(c.checked_sub(&b).unwrap() == a);
 1753  
 1754              if a > c {
 1755                  assert!(a.checked_sub(&c).is_none());
 1756              }
 1757              if b > c {
 1758                  assert!(b.checked_sub(&c).is_none());
 1759              }
 1760          }
 1761      }
 1762  
 1763      #[test]
 1764      fn test_checked_mul() {
 1765          for elm in mul_triples.iter() {
 1766              let (aVec, bVec, cVec) = *elm;
 1767              let a = BigUint::from_slice(aVec);
 1768              let b = BigUint::from_slice(bVec);
 1769              let c = BigUint::from_slice(cVec);
 1770  
 1771              assert!(a.checked_mul(&b).unwrap() == c);
 1772              assert!(b.checked_mul(&a).unwrap() == c);
 1773          }
 1774  
 1775          for elm in div_rem_quadruples.iter() {
 1776              let (aVec, bVec, cVec, dVec) = *elm;
 1777              let a = BigUint::from_slice(aVec);
 1778              let b = BigUint::from_slice(bVec);
 1779              let c = BigUint::from_slice(cVec);
 1780              let d = BigUint::from_slice(dVec);
 1781  
 1782              assert!(a == b.checked_mul(&c).unwrap() + d);
 1783              assert!(a == c.checked_mul(&b).unwrap() + d);
 1784          }
 1785      }
 1786  
 1787      #[test]
 1788      fn test_checked_div() {
 1789          for elm in mul_triples.iter() {
 1790              let (aVec, bVec, cVec) = *elm;
 1791              let a = BigUint::from_slice(aVec);
 1792              let b = BigUint::from_slice(bVec);
 1793              let c = BigUint::from_slice(cVec);
 1794  
 1795              if !a.is_zero() {
 1796                  assert!(c.checked_div(&a).unwrap() == b);
 1797              }
 1798              if !b.is_zero() {
 1799                  assert!(c.checked_div(&b).unwrap() == a);
 1800              }
 1801  
 1802              assert!(c.checked_div(&Zero::zero()).is_none());
 1803          }
 1804      }
 1805  
 1806      #[test]
 1807      fn test_gcd() {
 1808          fn check(a: uint, b: uint, c: uint) {
 1809              let big_a: BigUint = FromPrimitive::from_uint(a).unwrap();
 1810              let big_b: BigUint = FromPrimitive::from_uint(b).unwrap();
 1811              let big_c: BigUint = FromPrimitive::from_uint(c).unwrap();
 1812  
 1813              assert_eq!(big_a.gcd(&big_b), big_c);
 1814          }
 1815  
 1816          check(10, 2, 2);
 1817          check(10, 3, 1);
 1818          check(0, 3, 3);
 1819          check(3, 3, 3);
 1820          check(56, 42, 14);
 1821      }
 1822  
 1823      #[test]
 1824      fn test_lcm() {
 1825          fn check(a: uint, b: uint, c: uint) {
 1826              let big_a: BigUint = FromPrimitive::from_uint(a).unwrap();
 1827              let big_b: BigUint = FromPrimitive::from_uint(b).unwrap();
 1828              let big_c: BigUint = FromPrimitive::from_uint(c).unwrap();
 1829  
 1830              assert_eq!(big_a.lcm(&big_b), big_c);
 1831          }
 1832  
 1833          check(1, 0, 0);
 1834          check(0, 1, 0);
 1835          check(1, 1, 1);
 1836          check(8, 9, 72);
 1837          check(11, 5, 55);
 1838          check(99, 17, 1683);
 1839      }
 1840  
 1841      #[test]
 1842      fn test_is_even() {
 1843          let one: BigUint = FromStr::from_str("1").unwrap();
 1844          let two: BigUint = FromStr::from_str("2").unwrap();
 1845          let thousand: BigUint = FromStr::from_str("1000").unwrap();
 1846          let big: BigUint = FromStr::from_str("1000000000000000000000").unwrap();
 1847          let bigger: BigUint = FromStr::from_str("1000000000000000000001").unwrap();
 1848          assert!(one.is_odd());
 1849          assert!(two.is_even());
 1850          assert!(thousand.is_even());
 1851          assert!(big.is_even());
 1852          assert!(bigger.is_odd());
 1853          assert!((one << 64).is_even());
 1854          assert!(((one << 64) + one).is_odd());
 1855      }
 1856  
 1857      fn to_str_pairs() -> Vec<(BigUint, Vec<(uint, ~str)>){
 1858          let bits = BigDigit::bits;
 1859          vec!(( Zero::zero(), vec!(
 1860              (2, "0".to_owned()), (3, "0".to_owned())
 1861          )), ( BigUint::from_slice([ 0xff ]), vec!(
 1862              (2,  "11111111".to_owned()),
 1863              (3,  "100110".to_owned()),
 1864              (4,  "3333".to_owned()),
 1865              (5,  "2010".to_owned()),
 1866              (6,  "1103".to_owned()),
 1867              (7,  "513".to_owned()),
 1868              (8,  "377".to_owned()),
 1869              (9,  "313".to_owned()),
 1870              (10, "255".to_owned()),
 1871              (11, "212".to_owned()),
 1872              (12, "193".to_owned()),
 1873              (13, "168".to_owned()),
 1874              (14, "143".to_owned()),
 1875              (15, "120".to_owned()),
 1876              (16, "ff".to_owned())
 1877          )), ( BigUint::from_slice([ 0xfff ]), vec!(
 1878              (2,  "111111111111".to_owned()),
 1879              (4,  "333333".to_owned()),
 1880              (16, "fff".to_owned())
 1881          )), ( BigUint::from_slice([ 1, 2 ]), vec!(
 1882              (2,
 1883               "10".to_owned() +
 1884               "0".repeat(bits - 1) + "1"),
 1885              (4,
 1886               "2".to_owned() +
 1887               "0".repeat(bits / 2 - 1) + "1"),
 1888              (10, match bits {
 1889                  32 => "8589934593".to_owned(), 16 => "131073".to_owned(), _ => fail!()
 1890              }),
 1891              (16,
 1892               "2".to_owned() +
 1893               "0".repeat(bits / 4 - 1) + "1")
 1894          )), ( BigUint::from_slice([ 1, 2, 3 ]), vec!(
 1895              (2,
 1896               "11".to_owned() +
 1897               "0".repeat(bits - 2) + "10" +
 1898               "0".repeat(bits - 1) + "1"),
 1899              (4,
 1900               "3".to_owned() +
 1901               "0".repeat(bits / 2 - 1) + "2" +
 1902               "0".repeat(bits / 2 - 1) + "1"),
 1903              (10, match bits {
 1904                  32 => "55340232229718589441".to_owned(),
 1905                  16 => "12885032961".to_owned(),
 1906                  _ => fail!()
 1907              }),
 1908              (16, "3".to_owned() +
 1909               "0".repeat(bits / 4 - 1) + "2" +
 1910               "0".repeat(bits / 4 - 1) + "1")
 1911          )) )
 1912      }
 1913  
 1914      #[test]
 1915      fn test_to_str_radix() {
 1916          let r = to_str_pairs();
 1917          for num_pair in r.iter() {
 1918              let &(ref n, ref rs) = num_pair;
 1919              for str_pair in rs.iter() {
 1920                  let &(ref radix, ref str) = str_pair;
 1921                  assert_eq!(&n.to_str_radix(*radix), str);
 1922              }
 1923          }
 1924      }
 1925  
 1926      #[test]
 1927      fn test_from_str_radix() {
 1928          let r = to_str_pairs();
 1929          for num_pair in r.iter() {
 1930              let &(ref n, ref rs) = num_pair;
 1931              for str_pair in rs.iter() {
 1932                  let &(ref radix, ref str) = str_pair;
 1933                  assert_eq!(n, &FromStrRadix::from_str_radix(*str, *radix).unwrap());
 1934              }
 1935          }
 1936  
 1937          let zed: Option<BigUint> = FromStrRadix::from_str_radix("Z", 10);
 1938          assert_eq!(zed, None);
 1939          let blank: Option<BigUint> = FromStrRadix::from_str_radix("_", 2);
 1940          assert_eq!(blank, None);
 1941          let minus_one: Option<BigUint> = FromStrRadix::from_str_radix("-1",
 1942                                                                        10);
 1943          assert_eq!(minus_one, None);
 1944      }
 1945  
 1946      #[test]
 1947      fn test_factor() {
 1948          fn factor(n: uint) -> BigUint {
 1949              let mut f: BigUint = One::one();
 1950              for i in range(2, n + 1) {
 1951                  // FIXME(#5992): assignment operator overloads
 1952                  // f *= FromPrimitive::from_uint(i);
 1953                  f = f * FromPrimitive::from_uint(i).unwrap();
 1954              }
 1955              return f;
 1956          }
 1957  
 1958          fn check(n: uint, s: &str) {
 1959              let n = factor(n);
 1960              let ans = match FromStrRadix::from_str_radix(s, 10) {
 1961                  Some(x) => x, None => fail!()
 1962              };
 1963              assert_eq!(n, ans);
 1964          }
 1965  
 1966          check(3, "6");
 1967          check(10, "3628800");
 1968          check(20, "2432902008176640000");
 1969          check(30, "265252859812191058636308480000000");
 1970      }
 1971  
 1972      #[test]
 1973      fn test_bits() {
 1974          assert_eq!(BigUint::new(vec!(0,0,0,0)).bits(), 0);
 1975          let n: BigUint = FromPrimitive::from_uint(0).unwrap();
 1976          assert_eq!(n.bits(), 0);
 1977          let n: BigUint = FromPrimitive::from_uint(1).unwrap();
 1978          assert_eq!(n.bits(), 1);
 1979          let n: BigUint = FromPrimitive::from_uint(3).unwrap();
 1980          assert_eq!(n.bits(), 2);
 1981          let n: BigUint = FromStrRadix::from_str_radix("4000000000", 16).unwrap();
 1982          assert_eq!(n.bits(), 39);
 1983          let one: BigUint = One::one();
 1984          assert_eq!((one << 426).bits(), 427);
 1985      }
 1986  
 1987      #[test]
 1988      fn test_rand() {
 1989          let mut rng = task_rng();
 1990          let _n: BigUint = rng.gen_biguint(137);
 1991          assert!(rng.gen_biguint(0).is_zero());
 1992      }
 1993  
 1994      #[test]
 1995      fn test_rand_range() {
 1996          let mut rng = task_rng();
 1997  
 1998          for _ in range(0, 10) {
 1999              assert_eq!(rng.gen_bigint_range(&FromPrimitive::from_uint(236).unwrap(),
 2000                                              &FromPrimitive::from_uint(237).unwrap()),
 2001                         FromPrimitive::from_uint(236).unwrap());
 2002          }
 2003  
 2004          let l = FromPrimitive::from_uint(403469000 + 2352).unwrap();
 2005          let u = FromPrimitive::from_uint(403469000 + 3513).unwrap();
 2006          for _ in range(0, 1000) {
 2007              let n: BigUint = rng.gen_biguint_below(&u);
 2008              assert!(n < u);
 2009  
 2010              let n: BigUint = rng.gen_biguint_range(&l, &u);
 2011              assert!(n >= l);
 2012              assert!(n < u);
 2013          }
 2014      }
 2015  
 2016      #[test]
 2017      #[should_fail]
 2018      fn test_zero_rand_range() {
 2019          task_rng().gen_biguint_range(&FromPrimitive::from_uint(54).unwrap(),
 2020                                       &FromPrimitive::from_uint(54).unwrap());
 2021      }
 2022  
 2023      #[test]
 2024      #[should_fail]
 2025      fn test_negative_rand_range() {
 2026          let mut rng = task_rng();
 2027          let l = FromPrimitive::from_uint(2352).unwrap();
 2028          let u = FromPrimitive::from_uint(3513).unwrap();
 2029          // Switching u and l should fail:
 2030          let _n: BigUint = rng.gen_biguint_range(&u, &l);
 2031      }
 2032  }
 2033  
 2034  #[cfg(test)]
 2035  mod bigint_tests {
 2036      use Integer;
 2037      use super::{BigDigit, BigUint, ToBigUint};
 2038      use super::{Sign, Minus, Zero, Plus, BigInt, RandBigInt, ToBigInt};
 2039  
 2040      use std::cmp::{Less, Equal, Greater};
 2041      use std::i64;
 2042      use std::num::CheckedDiv;
 2043      use std::num::{Zero, One, FromStrRadix, ToStrRadix};
 2044      use std::num::{ToPrimitive, FromPrimitive};
 2045      use rand::{task_rng};
 2046      use std::u64;
 2047  
 2048      #[test]
 2049      fn test_from_biguint() {
 2050          fn check(inp_s: Sign, inp_n: uint, ans_s: Sign, ans_n: uint) {
 2051              let inp = BigInt::from_biguint(inp_s, FromPrimitive::from_uint(inp_n).unwrap());
 2052              let ans = BigInt { sign: ans_s, data: FromPrimitive::from_uint(ans_n).unwrap()};
 2053              assert_eq!(inp, ans);
 2054          }
 2055          check(Plus, 1, Plus, 1);
 2056          check(Plus, 0, Zero, 0);
 2057          check(Minus, 1, Minus, 1);
 2058          check(Zero, 1, Zero, 0);
 2059      }
 2060  
 2061      #[test]
 2062      fn test_cmp() {
 2063          let vs = [ &[2 as BigDigit], &[1, 1], &[2, 1], &[1, 1, 1] ];
 2064          let mut nums = Vec::new();
 2065          for s in vs.iter().rev() {
 2066              nums.push(BigInt::from_slice(Minus, *s));
 2067          }
 2068          nums.push(Zero::zero());
 2069          nums.extend(vs.iter().map(|s| BigInt::from_slice(Plus, *s)));
 2070  
 2071          for (i, ni) in nums.iter().enumerate() {
 2072              for (j0, nj) in nums.slice(i, nums.len()).iter().enumerate() {
 2073                  let j = i + j0;
 2074                  if i == j {
 2075                      assert_eq!(ni.cmp(nj), Equal);
 2076                      assert_eq!(nj.cmp(ni), Equal);
 2077                      assert_eq!(ni, nj);
 2078                      assert!(!(ni != nj));
 2079                      assert!(ni <= nj);
 2080                      assert!(ni >= nj);
 2081                      assert!(!(ni < nj));
 2082                      assert!(!(ni > nj));
 2083                  } else {
 2084                      assert_eq!(ni.cmp(nj), Less);
 2085                      assert_eq!(nj.cmp(ni), Greater);
 2086  
 2087                      assert!(!(ni == nj));
 2088                      assert!(ni != nj);
 2089  
 2090                      assert!(ni <= nj);
 2091                      assert!(!(ni >= nj));
 2092                      assert!(ni < nj);
 2093                      assert!(!(ni > nj));
 2094  
 2095                      assert!(!(nj <= ni));
 2096                      assert!(nj >= ni);
 2097                      assert!(!(nj < ni));
 2098                      assert!(nj > ni);
 2099                  }
 2100              }
 2101          }
 2102      }
 2103  
 2104      #[test]
 2105      fn test_convert_i64() {
 2106          fn check(b1: BigInt, i: i64) {
 2107              let b2: BigInt = FromPrimitive::from_i64(i).unwrap();
 2108              assert!(b1 == b2);
 2109              assert!(b1.to_i64().unwrap() == i);
 2110          }
 2111  
 2112          check(Zero::zero(), 0);
 2113          check(One::one(), 1);
 2114          check(i64::MIN.to_bigint().unwrap(), i64::MIN);
 2115          check(i64::MAX.to_bigint().unwrap(), i64::MAX);
 2116  
 2117          assert_eq!(
 2118              (i64::MAX as u64 + 1).to_bigint().unwrap().to_i64(),
 2119              None);
 2120  
 2121          assert_eq!(
 2122              BigInt::from_biguint(Plus,  BigUint::new(vec!(1, 2, 3, 4, 5))).to_i64(),
 2123              None);
 2124  
 2125          assert_eq!(
 2126              BigInt::from_biguint(Minus, BigUint::new(vec!(1,0,0,1<<(BigDigit::bits-1)))).to_i64(),
 2127              None);
 2128  
 2129          assert_eq!(
 2130              BigInt::from_biguint(Minus, BigUint::new(vec!(1, 2, 3, 4, 5))).to_i64(),
 2131              None);
 2132      }
 2133  
 2134      #[test]
 2135      fn test_convert_u64() {
 2136          fn check(b1: BigInt, u: u64) {
 2137              let b2: BigInt = FromPrimitive::from_u64(u).unwrap();
 2138              assert!(b1 == b2);
 2139              assert!(b1.to_u64().unwrap() == u);
 2140          }
 2141  
 2142          check(Zero::zero(), 0);
 2143          check(One::one(), 1);
 2144          check(u64::MIN.to_bigint().unwrap(), u64::MIN);
 2145          check(u64::MAX.to_bigint().unwrap(), u64::MAX);
 2146  
 2147          assert_eq!(
 2148              BigInt::from_biguint(Plus, BigUint::new(vec!(1, 2, 3, 4, 5))).to_u64(),
 2149              None);
 2150  
 2151          let max_value: BigUint = FromPrimitive::from_u64(u64::MAX).unwrap();
 2152          assert_eq!(BigInt::from_biguint(Minus, max_value).to_u64(), None);
 2153          assert_eq!(BigInt::from_biguint(Minus, BigUint::new(vec!(1, 2, 3, 4, 5))).to_u64(), None);
 2154      }
 2155  
 2156      #[test]
 2157      fn test_convert_to_biguint() {
 2158          fn check(n: BigInt, ans_1: BigUint) {
 2159              assert_eq!(n.to_biguint().unwrap(), ans_1);
 2160              assert_eq!(n.to_biguint().unwrap().to_bigint().unwrap(), n);
 2161          }
 2162          let zero: BigInt = Zero::zero();
 2163          let unsigned_zero: BigUint = Zero::zero();
 2164          let positive = BigInt::from_biguint(
 2165              Plus, BigUint::new(vec!(1,2,3)));
 2166          let negative = -positive;
 2167  
 2168          check(zero, unsigned_zero);
 2169          check(positive, BigUint::new(vec!(1,2,3)));
 2170  
 2171          assert_eq!(negative.to_biguint(), None);
 2172      }
 2173  
 2174      static sum_triples: &'static [(&'static [BigDigit],
 2175                                     &'static [BigDigit],
 2176                                     &'static [BigDigit])] = &[
 2177          (&[],          &[],       &[]),
 2178          (&[],          &[ 1],     &[ 1]),
 2179          (&[ 1],        &[ 1],     &[ 2]),
 2180          (&[ 1],        &[ 1,  1], &[ 2,  1]),
 2181          (&[ 1],        &[-1],     &[ 0,  1]),
 2182          (&[ 1],        &[-1, -1], &[ 0,  0, 1]),
 2183          (&[-1, -1],    &[-1, -1], &[-2, -1, 1]),
 2184          (&[ 1,  1, 1], &[-1, -1], &[ 0,  1, 2]),
 2185          (&[ 2,  2, 1], &[-1, -2], &[ 1,  1, 2])
 2186      ];
 2187  
 2188      #[test]
 2189      fn test_add() {
 2190          for elm in sum_triples.iter() {
 2191              let (a_vec, b_vec, c_vec) = *elm;
 2192              let a = BigInt::from_slice(Plus, a_vec);
 2193              let b = BigInt::from_slice(Plus, b_vec);
 2194              let c = BigInt::from_slice(Plus, c_vec);
 2195  
 2196              assert!(a + b == c);
 2197              assert!(b + a == c);
 2198              assert!(c + (-a) == b);
 2199              assert!(c + (-b) == a);
 2200              assert!(a + (-c) == (-b));
 2201              assert!(b + (-c) == (-a));
 2202              assert!((-a) + (-b) == (-c))
 2203              assert!(a + (-a) == Zero::zero());
 2204          }
 2205      }
 2206  
 2207      #[test]
 2208      fn test_sub() {
 2209          for elm in sum_triples.iter() {
 2210              let (a_vec, b_vec, c_vec) = *elm;
 2211              let a = BigInt::from_slice(Plus, a_vec);
 2212              let b = BigInt::from_slice(Plus, b_vec);
 2213              let c = BigInt::from_slice(Plus, c_vec);
 2214  
 2215              assert!(c - a == b);
 2216              assert!(c - b == a);
 2217              assert!((-b) - a == (-c))
 2218              assert!((-a) - b == (-c))
 2219              assert!(b - (-a) == c);
 2220              assert!(a - (-b) == c);
 2221              assert!((-c) - (-a) == (-b));
 2222              assert!(a - a == Zero::zero());
 2223          }
 2224      }
 2225  
 2226      static mul_triples: &'static [(&'static [BigDigit],
 2227                                     &'static [BigDigit],
 2228                                     &'static [BigDigit])] = &[
 2229          (&[],               &[],               &[]),
 2230          (&[],               &[ 1],             &[]),
 2231          (&[ 2],             &[],               &[]),
 2232          (&[ 1],             &[ 1],             &[1]),
 2233          (&[ 2],             &[ 3],             &[ 6]),
 2234          (&[ 1],             &[ 1,  1,  1],     &[1, 1,  1]),
 2235          (&[ 1,  2,  3],     &[ 3],             &[ 3,  6,  9]),
 2236          (&[ 1,  1,  1],     &[-1],             &[-1, -1, -1]),
 2237          (&[ 1,  2,  3],     &[-1],             &[-1, -2, -2, 2]),
 2238          (&[ 1,  2,  3,  4], &[-1],             &[-1, -2, -2, -2, 3]),
 2239          (&[-1],             &[-1],             &[ 1, -2]),
 2240          (&[-1, -1],         &[-1],             &[ 1, -1, -2]),
 2241          (&[-1, -1, -1],     &[-1],             &[ 1, -1, -1, -2]),
 2242          (&[-1, -1, -1, -1], &[-1],             &[ 1, -1, -1, -1, -2]),
 2243          (&[-1/2 + 1],       &[ 2],             &[ 0,  1]),
 2244          (&[0, -1/2 + 1],    &[ 2],             &[ 0,  0,  1]),
 2245          (&[ 1,  2],         &[ 1,  2,  3],     &[1, 4,  7,  6]),
 2246          (&[-1, -1],         &[-1, -1, -1],     &[1, 0, -1, -2, -1]),
 2247          (&[-1, -1, -1],     &[-1, -1, -1, -1], &[1, 0,  0, -1, -2, -1, -1]),
 2248          (&[ 0,  0,  1],     &[ 1,  2,  3],     &[0, 0,  1,  2,  3]),
 2249          (&[ 0,  0,  1],     &[ 0,  0,  0,  1], &[0, 0,  0,  0,  0,  1])
 2250      ];
 2251  
 2252      static div_rem_quadruples: &'static [(&'static [BigDigit],
 2253                                            &'static [BigDigit],
 2254                                            &'static [BigDigit],
 2255                                            &'static [BigDigit])]
 2256          = &[
 2257              (&[ 1],        &[ 2], &[],               &[1]),
 2258              (&[ 1,  1],    &[ 2], &[-1/2+1],         &[1]),
 2259              (&[ 1,  1, 1], &[ 2], &[-1/2+1, -1/2+1], &[1]),
 2260              (&[ 0,  1],    &[-1], &[1],              &[1]),
 2261              (&[-1, -1],    &[-2], &[2, 1],           &[3])
 2262          ];
 2263  
 2264      #[test]
 2265      fn test_mul() {
 2266          for elm in mul_triples.iter() {
 2267              let (a_vec, b_vec, c_vec) = *elm;
 2268              let a = BigInt::from_slice(Plus, a_vec);
 2269              let b = BigInt::from_slice(Plus, b_vec);
 2270              let c = BigInt::from_slice(Plus, c_vec);
 2271  
 2272              assert!(a * b == c);
 2273              assert!(b * a == c);
 2274  
 2275              assert!((-a) * b == -c);
 2276              assert!((-b) * a == -c);
 2277          }
 2278  
 2279          for elm in div_rem_quadruples.iter() {
 2280              let (a_vec, b_vec, c_vec, d_vec) = *elm;
 2281              let a = BigInt::from_slice(Plus, a_vec);
 2282              let b = BigInt::from_slice(Plus, b_vec);
 2283              let c = BigInt::from_slice(Plus, c_vec);
 2284              let d = BigInt::from_slice(Plus, d_vec);
 2285  
 2286              assert!(a == b * c + d);
 2287              assert!(a == c * b + d);
 2288          }
 2289      }
 2290  
 2291      #[test]
 2292      fn test_div_mod_floor() {
 2293          fn check_sub(a: &BigInt, b: &BigInt, ans_d: &BigInt, ans_m: &BigInt) {
 2294              let (d, m) = a.div_mod_floor(b);
 2295              if !m.is_zero() {
 2296                  assert_eq!(m.sign, b.sign);
 2297              }
 2298              assert!(m.abs() <= b.abs());
 2299              assert!(*a == b * d + m);
 2300              assert!(d == *ans_d);
 2301              assert!(m == *ans_m);
 2302          }
 2303  
 2304          fn check(a: &BigInt, b: &BigInt, d: &BigInt, m: &BigInt) {
 2305              if m.is_zero() {
 2306                  check_sub(a, b, d, m);
 2307                  check_sub(a, &b.neg(), &d.neg(), m);
 2308                  check_sub(&a.neg(), b, &d.neg(), m);
 2309                  check_sub(&a.neg(), &b.neg(), d, m);
 2310              } else {
 2311                  check_sub(a, b, d, m);
 2312                  check_sub(a, &b.neg(), &(d.neg() - One::one()), &(m - *b));
 2313                  check_sub(&a.neg(), b, &(d.neg() - One::one()), &(b - *m));
 2314                  check_sub(&a.neg(), &b.neg(), d, &m.neg());
 2315              }
 2316          }
 2317  
 2318          for elm in mul_triples.iter() {
 2319              let (a_vec, b_vec, c_vec) = *elm;
 2320              let a = BigInt::from_slice(Plus, a_vec);
 2321              let b = BigInt::from_slice(Plus, b_vec);
 2322              let c = BigInt::from_slice(Plus, c_vec);
 2323  
 2324              if !a.is_zero() { check(&c, &a, &b, &Zero::zero()); }
 2325              if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); }
 2326          }
 2327  
 2328          for elm in div_rem_quadruples.iter() {
 2329              let (a_vec, b_vec, c_vec, d_vec) = *elm;
 2330              let a = BigInt::from_slice(Plus, a_vec);
 2331              let b = BigInt::from_slice(Plus, b_vec);
 2332              let c = BigInt::from_slice(Plus, c_vec);
 2333              let d = BigInt::from_slice(Plus, d_vec);
 2334  
 2335              if !b.is_zero() {
 2336                  check(&a, &b, &c, &d);
 2337              }
 2338          }
 2339      }
 2340  
 2341  
 2342      #[test]
 2343      fn test_div_rem() {
 2344          fn check_sub(a: &BigInt, b: &BigInt, ans_q: &BigInt, ans_r: &BigInt) {
 2345              let (q, r) = a.div_rem(b);
 2346              if !r.is_zero() {
 2347                  assert_eq!(r.sign, a.sign);
 2348              }
 2349              assert!(r.abs() <= b.abs());
 2350              assert!(*a == b * q + r);
 2351              assert!(q == *ans_q);
 2352              assert!(r == *ans_r);
 2353          }
 2354  
 2355          fn check(a: &BigInt, b: &BigInt, q: &BigInt, r: &BigInt) {
 2356              check_sub(a, b, q, r);
 2357              check_sub(a, &b.neg(), &q.neg(), r);
 2358              check_sub(&a.neg(), b, &q.neg(), &r.neg());
 2359              check_sub(&a.neg(), &b.neg(), q, &r.neg());
 2360          }
 2361          for elm in mul_triples.iter() {
 2362              let (a_vec, b_vec, c_vec) = *elm;
 2363              let a = BigInt::from_slice(Plus, a_vec);
 2364              let b = BigInt::from_slice(Plus, b_vec);
 2365              let c = BigInt::from_slice(Plus, c_vec);
 2366  
 2367              if !a.is_zero() { check(&c, &a, &b, &Zero::zero()); }
 2368              if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); }
 2369          }
 2370  
 2371          for elm in div_rem_quadruples.iter() {
 2372              let (a_vec, b_vec, c_vec, d_vec) = *elm;
 2373              let a = BigInt::from_slice(Plus, a_vec);
 2374              let b = BigInt::from_slice(Plus, b_vec);
 2375              let c = BigInt::from_slice(Plus, c_vec);
 2376              let d = BigInt::from_slice(Plus, d_vec);
 2377  
 2378              if !b.is_zero() {
 2379                  check(&a, &b, &c, &d);
 2380              }
 2381          }
 2382      }
 2383  
 2384      #[test]
 2385      fn test_checked_add() {
 2386          for elm in sum_triples.iter() {
 2387              let (aVec, bVec, cVec) = *elm;
 2388              let a = BigInt::from_slice(Plus, aVec);
 2389              let b = BigInt::from_slice(Plus, bVec);
 2390              let c = BigInt::from_slice(Plus, cVec);
 2391  
 2392              assert!(a.checked_add(&b).unwrap() == c);
 2393              assert!(b.checked_add(&a).unwrap() == c);
 2394              assert!(c.checked_add(&(-a)).unwrap() == b);
 2395              assert!(c.checked_add(&(-b)).unwrap() == a);
 2396              assert!(a.checked_add(&(-c)).unwrap() == (-b));
 2397              assert!(b.checked_add(&(-c)).unwrap() == (-a));
 2398              assert!((-a).checked_add(&(-b)).unwrap() == (-c))
 2399              assert!(a.checked_add(&(-a)).unwrap() == Zero::zero());
 2400          }
 2401      }
 2402  
 2403      #[test]
 2404      fn test_checked_sub() {
 2405          for elm in sum_triples.iter() {
 2406              let (aVec, bVec, cVec) = *elm;
 2407              let a = BigInt::from_slice(Plus, aVec);
 2408              let b = BigInt::from_slice(Plus, bVec);
 2409              let c = BigInt::from_slice(Plus, cVec);
 2410  
 2411              assert!(c.checked_sub(&a).unwrap() == b);
 2412              assert!(c.checked_sub(&b).unwrap() == a);
 2413              assert!((-b).checked_sub(&a).unwrap() == (-c))
 2414              assert!((-a).checked_sub(&b).unwrap() == (-c))
 2415              assert!(b.checked_sub(&(-a)).unwrap() == c);
 2416              assert!(a.checked_sub(&(-b)).unwrap() == c);
 2417              assert!((-c).checked_sub(&(-a)).unwrap() == (-b));
 2418              assert!(a.checked_sub(&a).unwrap() == Zero::zero());
 2419          }
 2420      }
 2421  
 2422      #[test]
 2423      fn test_checked_mul() {
 2424          for elm in mul_triples.iter() {
 2425              let (aVec, bVec, cVec) = *elm;
 2426              let a = BigInt::from_slice(Plus, aVec);
 2427              let b = BigInt::from_slice(Plus, bVec);
 2428              let c = BigInt::from_slice(Plus, cVec);
 2429  
 2430              assert!(a.checked_mul(&b).unwrap() == c);
 2431              assert!(b.checked_mul(&a).unwrap() == c);
 2432  
 2433              assert!((-a).checked_mul(&b).unwrap() == -c);
 2434              assert!((-b).checked_mul(&a).unwrap() == -c);
 2435          }
 2436  
 2437          for elm in div_rem_quadruples.iter() {
 2438              let (aVec, bVec, cVec, dVec) = *elm;
 2439              let a = BigInt::from_slice(Plus, aVec);
 2440              let b = BigInt::from_slice(Plus, bVec);
 2441              let c = BigInt::from_slice(Plus, cVec);
 2442              let d = BigInt::from_slice(Plus, dVec);
 2443  
 2444              assert!(a == b.checked_mul(&c).unwrap() + d);
 2445              assert!(a == c.checked_mul(&b).unwrap() + d);
 2446          }
 2447      }
 2448      #[test]
 2449      fn test_checked_div() {
 2450          for elm in mul_triples.iter() {
 2451              let (aVec, bVec, cVec) = *elm;
 2452              let a = BigInt::from_slice(Plus, aVec);
 2453              let b = BigInt::from_slice(Plus, bVec);
 2454              let c = BigInt::from_slice(Plus, cVec);
 2455  
 2456              if !a.is_zero() {
 2457                  assert!(c.checked_div(&a).unwrap() == b);
 2458                  assert!((-c).checked_div(&(-a)).unwrap() == b);
 2459                  assert!((-c).checked_div(&a).unwrap() == -b);
 2460              }
 2461              if !b.is_zero() {
 2462                  assert!(c.checked_div(&b).unwrap() == a);
 2463                  assert!((-c).checked_div(&(-b)).unwrap() == a);
 2464                  assert!((-c).checked_div(&b).unwrap() == -a);
 2465              }
 2466  
 2467              assert!(c.checked_div(&Zero::zero()).is_none());
 2468              assert!((-c).checked_div(&Zero::zero()).is_none());
 2469          }
 2470      }
 2471  
 2472      #[test]
 2473      fn test_gcd() {
 2474          fn check(a: int, b: int, c: int) {
 2475              let big_a: BigInt = FromPrimitive::from_int(a).unwrap();
 2476              let big_b: BigInt = FromPrimitive::from_int(b).unwrap();
 2477              let big_c: BigInt = FromPrimitive::from_int(c).unwrap();
 2478  
 2479              assert_eq!(big_a.gcd(&big_b), big_c);
 2480          }
 2481  
 2482          check(10, 2, 2);
 2483          check(10, 3, 1);
 2484          check(0, 3, 3);
 2485          check(3, 3, 3);
 2486          check(56, 42, 14);
 2487          check(3, -3, 3);
 2488          check(-6, 3, 3);
 2489          check(-4, -2, 2);
 2490      }
 2491  
 2492      #[test]
 2493      fn test_lcm() {
 2494          fn check(a: int, b: int, c: int) {
 2495              let big_a: BigInt = FromPrimitive::from_int(a).unwrap();
 2496              let big_b: BigInt = FromPrimitive::from_int(b).unwrap();
 2497              let big_c: BigInt = FromPrimitive::from_int(c).unwrap();
 2498  
 2499              assert_eq!(big_a.lcm(&big_b), big_c);
 2500          }
 2501  
 2502          check(1, 0, 0);
 2503          check(0, 1, 0);
 2504          check(1, 1, 1);
 2505          check(-1, 1, 1);
 2506          check(1, -1, 1);
 2507          check(-1, -1, 1);
 2508          check(8, 9, 72);
 2509          check(11, 5, 55);
 2510      }
 2511  
 2512      #[test]
 2513      fn test_abs_sub() {
 2514          let zero: BigInt = Zero::zero();
 2515          let one: BigInt = One::one();
 2516          assert_eq!((-one).abs_sub(&one), zero);
 2517          let one: BigInt = One::one();
 2518          let zero: BigInt = Zero::zero();
 2519          assert_eq!(one.abs_sub(&one), zero);
 2520          let one: BigInt = One::one();
 2521          let zero: BigInt = Zero::zero();
 2522          assert_eq!(one.abs_sub(&zero), one);
 2523          let one: BigInt = One::one();
 2524          let two: BigInt = FromPrimitive::from_int(2).unwrap();
 2525          assert_eq!(one.abs_sub(&-one), two);
 2526      }
 2527  
 2528      #[test]
 2529      fn test_to_str_radix() {
 2530          fn check(n: int, ans: &str) {
 2531              let n: BigInt = FromPrimitive::from_int(n).unwrap();
 2532              assert!(ans == n.to_str_radix(10));
 2533          }
 2534          check(10, "10");
 2535          check(1, "1");
 2536          check(0, "0");
 2537          check(-1, "-1");
 2538          check(-10, "-10");
 2539      }
 2540  
 2541  
 2542      #[test]
 2543      fn test_from_str_radix() {
 2544          fn check(s: &str, ans: Option<int>) {
 2545              let ans = ans.map(|n| {
 2546                  let x: BigInt = FromPrimitive::from_int(n).unwrap();
 2547                  x
 2548              });
 2549              assert_eq!(FromStrRadix::from_str_radix(s, 10), ans);
 2550          }
 2551          check("10", Some(10));
 2552          check("1", Some(1));
 2553          check("0", Some(0));
 2554          check("-1", Some(-1));
 2555          check("-10", Some(-10));
 2556          check("Z", None);
 2557          check("_", None);
 2558  
 2559          // issue 10522, this hit an edge case that caused it to
 2560          // attempt to allocate a vector of size (-1u) == huge.
 2561          let x: BigInt = from_str("1" + "0".repeat(36)).unwrap();
 2562          let _y = x.to_str();
 2563      }
 2564  
 2565      #[test]
 2566      fn test_neg() {
 2567          assert!(-BigInt::new(Plus,  vec!(1, 1, 1)) ==
 2568              BigInt::new(Minus, vec!(1, 1, 1)));
 2569          assert!(-BigInt::new(Minus, vec!(1, 1, 1)) ==
 2570              BigInt::new(Plus,  vec!(1, 1, 1)));
 2571          let zero: BigInt = Zero::zero();
 2572          assert_eq!(-zero, zero);
 2573      }
 2574  
 2575      #[test]
 2576      fn test_rand() {
 2577          let mut rng = task_rng();
 2578          let _n: BigInt = rng.gen_bigint(137);
 2579          assert!(rng.gen_bigint(0).is_zero());
 2580      }
 2581  
 2582      #[test]
 2583      fn test_rand_range() {
 2584          let mut rng = task_rng();
 2585  
 2586          for _ in range(0, 10) {
 2587              assert_eq!(rng.gen_bigint_range(&FromPrimitive::from_uint(236).unwrap(),
 2588                                              &FromPrimitive::from_uint(237).unwrap()),
 2589                         FromPrimitive::from_uint(236).unwrap());
 2590          }
 2591  
 2592          fn check(l: BigInt, u: BigInt) {
 2593              let mut rng = task_rng();
 2594              for _ in range(0, 1000) {
 2595                  let n: BigInt = rng.gen_bigint_range(&l, &u);
 2596                  assert!(n >= l);
 2597                  assert!(n < u);
 2598              }
 2599          }
 2600          let l: BigInt = FromPrimitive::from_uint(403469000 + 2352).unwrap();
 2601          let u: BigInt = FromPrimitive::from_uint(403469000 + 3513).unwrap();
 2602          check( l.clone(),  u.clone());
 2603          check(-l.clone(),  u.clone());
 2604          check(-u.clone(), -l.clone());
 2605      }
 2606  
 2607      #[test]
 2608      #[should_fail]
 2609      fn test_zero_rand_range() {
 2610          task_rng().gen_bigint_range(&FromPrimitive::from_int(54).unwrap(),
 2611                                      &FromPrimitive::from_int(54).unwrap());
 2612      }
 2613  
 2614      #[test]
 2615      #[should_fail]
 2616      fn test_negative_rand_range() {
 2617          let mut rng = task_rng();
 2618          let l = FromPrimitive::from_uint(2352).unwrap();
 2619          let u = FromPrimitive::from_uint(3513).unwrap();
 2620          // Switching u and l should fail:
 2621          let _n: BigInt = rng.gen_bigint_range(&u, &l);
 2622      }
 2623  }
 2624  
 2625  #[cfg(test)]
 2626  mod bench {
 2627      extern crate test;
 2628      use self::test::Bencher;
 2629      use super::BigUint;
 2630      use std::iter;
 2631      use std::mem::replace;
 2632      use std::num::{FromPrimitive, Zero, One};
 2633  
 2634      fn factorial(n: uint) -> BigUint {
 2635          let mut f: BigUint = One::one();
 2636          for i in iter::range_inclusive(1, n) {
 2637              f = f * FromPrimitive::from_uint(i).unwrap();
 2638          }
 2639          f
 2640      }
 2641  
 2642      fn fib(n: uint) -> BigUint {
 2643          let mut f0: BigUint = Zero::zero();
 2644          let mut f1: BigUint = One::one();
 2645          for _ in range(0, n) {
 2646              let f2 = f0 + f1;
 2647              f0 = replace(&mut f1, f2);
 2648          }
 2649          f0
 2650      }
 2651  
 2652      #[bench]
 2653      fn factorial_100(b: &mut Bencher) {
 2654          b.iter(|| {
 2655              factorial(100);
 2656          });
 2657      }
 2658  
 2659      #[bench]
 2660      fn fib_100(b: &mut Bencher) {
 2661          b.iter(|| {
 2662              fib(100);
 2663          });
 2664      }
 2665  
 2666      #[bench]
 2667      fn to_str(b: &mut Bencher) {
 2668          let fac = factorial(100);
 2669          let fib = fib(100);
 2670          b.iter(|| {
 2671              fac.to_str();
 2672          });
 2673          b.iter(|| {
 2674              fib.to_str();
 2675          });
 2676      }
 2677  
 2678      #[bench]
 2679      fn shr(b: &mut Bencher) {
 2680          let n = { let one : BigUint = One::one(); one << 1000 };
 2681          b.iter(|| {
 2682              let mut m = n.clone();
 2683              for _ in range(0, 10) {
 2684                  m = m >> 1;
 2685              }
 2686          })
 2687      }
 2688  }


libnum/bigint.rs:40:3-40:3 -NK_AS_STR_TODO- definition:
*/
pub type DoubleBigDigit = u64;
pub static ZERO_BIG_DIGIT: BigDigit = 0;
references:- 24
609:         fn convert_base(n: &BigUint, base: DoubleBigDigit) -> Vec<BigDigit> {
610:             let divider    = base.to_biguint().unwrap();
--
715:             let (hi, lo) = BigDigit::from_doublebigdigit(
716:                 (*elem as DoubleBigDigit) << n_bits | (carry as DoubleBigDigit)
717:             );
--
758: fn get_radix_base(radix: uint) -> (DoubleBigDigit, uint) {
759:     assert!(1 < radix && radix <= 16);


libnum/bigint.rs:1153:58-1153:58 -trait- definition:
/// A generic trait for converting a value to a `BigInt`.
pub trait ToBigInt {
    /// Converts the value of `self` to a `BigInt`.
references:- 12
1178:     ($T:ty, $from_ty:path) => {
1179:         impl ToBigInt for $T {
1180:             #[inline]


libnum/bigint.rs:69:4-69:4 -fn- definition:
    pub fn to_doublebigdigit(hi: BigDigit, lo: BigDigit) -> DoubleBigDigit {
        (lo as DoubleBigDigit) | ((hi as DoubleBigDigit) << bits)
    }
references:- 2
520:             1 => Some(self.data.as_slice()[0] as u64),
521:             2 => Some(BigDigit::to_doublebigdigit(self.data.as_slice()[1], self.data.as_slice()[0])
522:                       as u64),


libnum/bigint.rs:63:4-63:4 -fn- definition:
    pub fn from_doublebigdigit(n: DoubleBigDigit) -> (BigDigit, BigDigit) {
        (get_hi(n), get_lo(n))
    }
references:- 5
542:     fn from_u64(n: u64) -> Option<BigUint> {
543:         let n = match BigDigit::from_doublebigdigit(n) {
544:             (0,  0)  => Zero::zero(),
--
714:         let mut shifted: Vec<BigDigit> = self.data.iter().map(|elem| {
715:             let (hi, lo) = BigDigit::from_doublebigdigit(
716:                 (*elem as DoubleBigDigit) << n_bits | (carry as DoubleBigDigit)


libnum/bigint.rs:285:8-285:8 -fn- definition:
        fn cut_at(a: &BigUint, n: uint) -> (BigUint, BigUint) {
            let mid = cmp::min(a.data.len(), n);
            return (BigUint::from_slice(a.data.slice(mid, a.data.len())),
references:- 2
250:         let (s_hi, s_lo) = cut_at(self,  half_len);
251:         let (o_hi, o_lo) = cut_at(other, half_len);


libnum/bigint.rs:268:8-268:8 -fn- definition:
        fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint {
            if n == 0 { return Zero::zero(); }
            if n == 1 { return (*a).clone(); }
references:- 2
241:         if s_len == 1 { return mul_digit(other, self.data.as_slice()[0]);  }
242:         if o_len == 1 { return mul_digit(self,  other.data.as_slice()[0]); }


libnum/bigint.rs:757:10-757:10 -fn- definition:
fn get_radix_base(radix: uint) -> (DoubleBigDigit, uint) {
    assert!(1 < radix && radix <= 16);
    match radix {
references:- 2
602:         assert!(1 < radix && radix <= 16);
603:         let (base, max_len) = get_radix_base(radix);
604:         if base == BigDigit::base {
--
666:     pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigUint> {
667:         let (base, unit_len) = get_radix_base(radix);
668:         let base_num = match base.to_biguint() {


libnum/bigint.rs:781:53-781:53 -enum- definition:
pub enum Sign { Minus, Zero, Plus }
impl Neg<Sign> for Sign {
    /// Negate Sign value.
references:- 22
780: /// A Sign is a `BigInt`'s composing element.
782: pub enum Sign { Minus, Zero, Plus }
--
1320:     #[inline]
1321:     pub fn from_slice(sign: Sign, slice: &[BigDigit]) -> BigInt {
1322:         BigInt::from_biguint(sign, BigUint::from_slice(slice))
libnum/rational.rs:
158:         let (mantissa, exponent, sign) = f.integer_decode();
159:         let bigint_sign: Sign = if sign == 1 { Plus } else { Minus };
160:         if exponent < 0 {
libnum/bigint.rs:
780: /// A Sign is a `BigInt`'s composing element.
782: pub enum Sign { Minus, Zero, Plus }


libnum/bigint.rs:80:19-80:19 -struct- definition:
pub struct BigUint {
    data: Vec<BigDigit>
}
references:- 169
libnum/rational.rs:
libnum/bigint.rs:


libnum/bigint.rs:292:8-292:8 -fn- definition:
        fn sub_sign(a: BigUint, b: BigUint) -> (Ordering, BigUint) {
            match a.cmp(&b) {
                Less    => (Less,    b - a),
references:- 2
256:             let (s1, n1) = sub_sign(s_hi, s_lo);
257:             let (s2, n2) = sub_sign(o_hi, o_lo);
258:             match (s1, s2) {


libnum/bigint.rs:34:3-34:3 -NK_AS_STR_TODO- definition:
*/
pub type BigDigit = u32;
/**
references:- 27
660:     #[inline]
661:     pub fn from_slice(slice: &[BigDigit]) -> BigUint {
662:         return BigUint::new(Vec::from_slice(slice));
--
713:         let mut carry = 0;
714:         let mut shifted: Vec<BigDigit> = self.data.iter().map(|elem| {
715:             let (hi, lo) = BigDigit::from_doublebigdigit(
--
1305:     #[inline]
1306:     pub fn new(sign: Sign, v: Vec<BigDigit>) -> BigInt {
1307:         BigInt::from_biguint(sign, BigUint::new(v))
--
1320:     #[inline]
1321:     pub fn from_slice(sign: Sign, slice: &[BigDigit]) -> BigInt {
1322:         BigInt::from_biguint(sign, BigUint::from_slice(slice))


libnum/bigint.rs:797:19-797:19 -struct- definition:
pub struct BigInt {
    sign: Sign,
    data: BigUint
references:- 128
libnum/rational.rs:
libnum/bigint.rs:


libnum/bigint.rs:624:8-624:8 -fn- definition:
        fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> ~str {
            if v.is_empty() { return "0".to_owned() }
            let mut s = StrBuf::with_capacity(v.len() * l);
references:- 2
604:         if base == BigDigit::base {
605:             return fill_concat(self.data.as_slice(), radix, max_len)
606:         }
607:         return fill_concat(convert_base(self, base).as_slice(), radix, max_len);


libnum/bigint.rs:552:59-552:59 -trait- definition:
/// A generic trait for converting a value to a `BigUint`.
pub trait ToBigUint {
    /// Converts the value of `self` to a `BigUint`.
references:- 12
579:     ($T:ty, $from_ty:path) => {
580:         impl ToBigUint for $T {
581:             #[inline]