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.
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.
13 A Big integer (signed version: `BigInt`, unsigned version: `BigUint`).
15 A `BigUint` is represented as an array of `BigDigit`s.
16 A `BigInt` is a combination of `BigUint` and `Sign`.
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};
34 A `BigDigit` is a `BigUint`'s composing element.
36 A `BigDigit` is half the size of machine word size.
38 #[cfg(target_word_size = "32")]
39 pub type BigDigit = u16;
42 A `BigDigit` is a `BigUint`'s composing element.
44 A `BigDigit` is half the size of machine word size.
46 #[cfg(target_word_size = "64")]
47 pub type BigDigit = u32;
49 pub static ZERO_BIG_DIGIT: BigDigit = 0;
50 static ZERO_VEC: [BigDigit, ..1] = [ZERO_BIG_DIGIT];
55 #[cfg(target_word_size = "32")]
56 pub static bits: uint = 16;
58 #[cfg(target_word_size = "64")]
59 pub static bits: uint = 32;
61 pub static base: uint = 1 << bits;
62 static lo_mask: uint = (-1 as uint) >> bits;
65 fn get_hi(n: uint) -> BigDigit { (n >> bits) as BigDigit }
67 fn get_lo(n: uint) -> BigDigit { (n & lo_mask) as BigDigit }
69 /// Split one machine sized unsigned integer into two `BigDigit`s.
71 pub fn from_uint(n: uint) -> (BigDigit, BigDigit) {
72 (get_hi(n), get_lo(n))
75 /// Join two `BigDigit`s into one machine sized unsigned integer
77 pub fn to_uint(hi: BigDigit, lo: BigDigit) -> uint {
78 (lo as uint) | ((hi as uint) << bits)
83 A big unsigned integer type.
85 A `BigUint`-typed value `BigUint { data: ~[a, b, c] }` represents a number
86 `(a + b * BigDigit::base + c * BigDigit::base^2)`.
90 priv data: Vec<BigDigit>
95 fn eq(&self, other: &BigUint) -> bool { self.equals(other) }
98 impl TotalEq for BigUint {
100 fn equals(&self, other: &BigUint) -> bool {
101 match self.cmp(other) { Equal => true, _ => false }
105 impl Ord for BigUint {
107 fn lt(&self, other: &BigUint) -> bool {
108 match self.cmp(other) { Less => true, _ => false}
112 impl TotalOrd for BigUint {
114 fn cmp(&self, other: &BigUint) -> Ordering {
115 let (s_len, o_len) = (self.data.len(), other.data.len());
116 if s_len < o_len { return Less; }
117 if s_len > o_len { return Greater; }
119 for (&self_i, &other_i) in self.data.iter().rev().zip(other.data.iter().rev()) {
120 if self_i < other_i { return Less; }
121 if self_i > other_i { return Greater; }
127 impl fmt::Show for BigUint {
128 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
129 write!(f.buf, "{}", self.to_str_radix(10))
133 impl FromStr for BigUint {
135 fn from_str(s: &str) -> Option<BigUint> {
136 FromStrRadix::from_str_radix(s, 10)
140 impl Num for BigUint {}
142 impl BitAnd<BigUint, BigUint> for BigUint {
143 fn bitand(&self, other: &BigUint) -> BigUint {
144 BigUint::new(self.data.iter().zip(other.data.iter()).map(|(ai, bi)| *ai & *bi).collect())
148 impl BitOr<BigUint, BigUint> for BigUint {
149 fn bitor(&self, other: &BigUint) -> BigUint {
150 let zeros = ZERO_VEC.iter().cycle();
151 let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
152 let ored = a.data.iter().zip(b.data.iter().chain(zeros)).map(
155 return BigUint::new(ored);
159 impl BitXor<BigUint, BigUint> for BigUint {
160 fn bitxor(&self, other: &BigUint) -> BigUint {
161 let zeros = ZERO_VEC.iter().cycle();
162 let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
163 let xored = a.data.iter().zip(b.data.iter().chain(zeros)).map(
166 return BigUint::new(xored);
170 impl Shl<uint, BigUint> for BigUint {
172 fn shl(&self, rhs: &uint) -> BigUint {
173 let n_unit = *rhs / BigDigit::bits;
174 let n_bits = *rhs % BigDigit::bits;
175 return self.shl_unit(n_unit).shl_bits(n_bits);
179 impl Shr<uint, BigUint> for BigUint {
181 fn shr(&self, rhs: &uint) -> BigUint {
182 let n_unit = *rhs / BigDigit::bits;
183 let n_bits = *rhs % BigDigit::bits;
184 return self.shr_unit(n_unit).shr_bits(n_bits);
188 impl Zero for BigUint {
190 fn zero() -> BigUint { BigUint::new(Vec::new()) }
193 fn is_zero(&self) -> bool { self.data.is_empty() }
196 impl One for BigUint {
198 fn one() -> BigUint { BigUint::new(vec!(1)) }
201 impl Unsigned for BigUint {}
203 impl Add<BigUint, BigUint> for BigUint {
204 fn add(&self, other: &BigUint) -> BigUint {
205 let zeros = ZERO_VEC.iter().cycle();
206 let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
209 let mut sum: Vec<BigDigit> = a.data.iter().zip(b.data.iter().chain(zeros)).map(|(ai, bi)| {
210 let (hi, lo) = BigDigit::from_uint((*ai as uint) + (*bi as uint) + (carry as uint));
214 if carry != 0 { sum.push(carry); }
215 return BigUint::new(sum);
219 impl Sub<BigUint, BigUint> for BigUint {
220 fn sub(&self, other: &BigUint) -> BigUint {
221 let new_len = cmp::max(self.data.len(), other.data.len());
222 let zeros = ZERO_VEC.iter().cycle();
223 let (a, b) = (self.data.iter().chain(zeros.clone()), other.data.iter().chain(zeros));
226 let diff: Vec<BigDigit> = a.take(new_len).zip(b).map(|(ai, bi)| {
227 let (hi, lo) = BigDigit::from_uint(
228 BigDigit::base + (*ai as uint) - (*bi as uint) - (borrow as uint)
231 hi * (base) + lo == 1*(base) + ai - bi - borrow
232 => ai - bi - borrow < 0 <=> hi == 0
234 borrow = if hi == 0 { 1 } else { 0 };
238 assert_eq!(borrow, 0); // <=> assert!((self >= other));
239 return BigUint::new(diff);
243 impl Mul<BigUint, BigUint> for BigUint {
244 fn mul(&self, other: &BigUint) -> BigUint {
245 if self.is_zero() || other.is_zero() { return Zero::zero(); }
247 let (s_len, o_len) = (self.data.len(), other.data.len());
248 if s_len == 1 { return mul_digit(other, self.data.as_slice()[0]); }
249 if o_len == 1 { return mul_digit(self, other.data.as_slice()[0]); }
251 // Using Karatsuba multiplication
252 // (a1 * base + a0) * (b1 * base + b0)
253 // = a1*b1 * base^2 +
254 // (a1*b1 + a0*b0 - (a1-b0)*(b1-a0)) * base +
256 let half_len = cmp::max(s_len, o_len) / 2;
257 let (s_hi, s_lo) = cut_at(self, half_len);
258 let (o_hi, o_lo) = cut_at(other, half_len);
260 let ll = s_lo * o_lo;
261 let hh = s_hi * o_hi;
263 let (s1, n1) = sub_sign(s_hi, s_lo);
264 let (s2, n2) = sub_sign(o_hi, o_lo);
266 (Equal, _) | (_, Equal) => hh + ll,
267 (Less, Greater) | (Greater, Less) => hh + ll + (n1 * n2),
268 (Less, Less) | (Greater, Greater) => hh + ll - (n1 * n2)
272 return ll + mm.shl_unit(half_len) + hh.shl_unit(half_len * 2);
275 fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint {
276 if n == 0 { return Zero::zero(); }
277 if n == 1 { return (*a).clone(); }
280 let mut prod: Vec<BigDigit> = a.data.iter().map(|ai| {
281 let (hi, lo) = BigDigit::from_uint(
282 (*ai as uint) * (n as uint) + (carry as uint)
287 if carry != 0 { prod.push(carry); }
288 return BigUint::new(prod);
292 fn cut_at(a: &BigUint, n: uint) -> (BigUint, BigUint) {
293 let mid = cmp::min(a.data.len(), n);
294 return (BigUint::from_slice(a.data.slice(mid, a.data.len())),
295 BigUint::from_slice(a.data.slice(0, mid)));
299 fn sub_sign(a: BigUint, b: BigUint) -> (Ordering, BigUint) {
301 Less => (Less, b - a),
302 Greater => (Greater, a - b),
303 _ => (Equal, Zero::zero())
309 impl Div<BigUint, BigUint> for BigUint {
311 fn div(&self, other: &BigUint) -> BigUint {
312 let (q, _) = self.div_rem(other);
317 impl Rem<BigUint, BigUint> for BigUint {
319 fn rem(&self, other: &BigUint) -> BigUint {
320 let (_, r) = self.div_rem(other);
325 impl Neg<BigUint> for BigUint {
327 fn neg(&self) -> BigUint { fail!() }
330 impl CheckedAdd for BigUint {
332 fn checked_add(&self, v: &BigUint) -> Option<BigUint> {
333 return Some(self.add(v));
337 impl CheckedSub for BigUint {
339 fn checked_sub(&self, v: &BigUint) -> Option<BigUint> {
343 return Some(self.sub(v));
347 impl CheckedMul for BigUint {
349 fn checked_mul(&self, v: &BigUint) -> Option<BigUint> {
350 return Some(self.mul(v));
354 impl CheckedDiv for BigUint {
356 fn checked_div(&self, v: &BigUint) -> Option<BigUint> {
360 return Some(self.div(v));
364 impl Integer for BigUint {
366 fn div_rem(&self, other: &BigUint) -> (BigUint, BigUint) {
367 self.div_mod_floor(other)
371 fn div_floor(&self, other: &BigUint) -> BigUint {
372 let (d, _) = self.div_mod_floor(other);
377 fn mod_floor(&self, other: &BigUint) -> BigUint {
378 let (_, m) = self.div_mod_floor(other);
382 fn div_mod_floor(&self, other: &BigUint) -> (BigUint, BigUint) {
383 if other.is_zero() { fail!() }
384 if self.is_zero() { return (Zero::zero(), Zero::zero()); }
385 if *other == One::one() { return ((*self).clone(), Zero::zero()); }
387 match self.cmp(other) {
388 Less => return (Zero::zero(), (*self).clone()),
389 Equal => return (One::one(), Zero::zero()),
390 Greater => {} // Do nothing
394 let mut n = *other.data.last().unwrap();
395 while n < (1 << BigDigit::bits - 2) {
399 assert!(shift < BigDigit::bits);
400 let (d, m) = div_mod_floor_inner(self << shift, other << shift);
401 return (d, m >> shift);
404 fn div_mod_floor_inner(a: BigUint, b: BigUint) -> (BigUint, BigUint) {
406 let mut d: BigUint = Zero::zero();
409 let (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
411 let mut prod = b * d0;
413 // FIXME(#6050): overloaded operators force moves with generic types
416 // FIXME(#6050): overloaded operators force moves with generic types
417 // prod = prod - b_unit;
425 // FIXME(#6102): Assignment operator for BigInt causes ICE
428 // FIXME(#6102): Assignment operator for BigInt causes ICE
436 fn div_estimate(a: &BigUint, b: &BigUint, n: uint)
437 -> (BigUint, BigUint, BigUint) {
438 if a.data.len() < n {
439 return (Zero::zero(), Zero::zero(), (*a).clone());
442 let an = a.data.tailn(a.data.len() - n);
443 let bn = *b.data.last().unwrap();
444 let mut d = Vec::with_capacity(an.len());
446 for elt in an.rev_iter() {
447 let ai = BigDigit::to_uint(carry, *elt);
448 let di = ai / (bn as uint);
449 assert!(di < BigDigit::base);
450 carry = (ai % (bn as uint)) as BigDigit;
451 d.push(di as BigDigit)
455 let shift = (a.data.len() - an.len()) - (b.data.len() - 1);
457 return (BigUint::new(d), One::one(), (*b).clone());
459 let one: BigUint = One::one();
460 return (BigUint::new(d).shl_unit(shift),
467 * Calculates the Greatest Common Divisor (GCD) of the number and `other`
469 * The result is always positive
472 fn gcd(&self, other: &BigUint) -> BigUint {
473 // Use Euclid's algorithm
474 let mut m = (*self).clone();
475 let mut n = (*other).clone();
485 * Calculates the Lowest Common Multiple (LCM) of the number and `other`
488 fn lcm(&self, other: &BigUint) -> BigUint { ((*self * *other) / self.gcd(other)) }
490 /// Returns `true` if the number can be divided by `other` without leaving a remainder
492 fn divides(&self, other: &BigUint) -> bool { (*self % *other).is_zero() }
494 /// Returns `true` if the number is divisible by `2`
496 fn is_even(&self) -> bool {
497 // Considering only the last digit.
498 match self.data.as_slice().head() {
499 Some(x) => x.is_even(),
504 /// Returns `true` if the number is not divisible by `2`
506 fn is_odd(&self) -> bool { !self.is_even() }
509 impl ToPrimitive for BigUint {
511 fn to_i64(&self) -> Option<i64> {
512 self.to_u64().and_then(|n| {
513 // If top bit of u64 is set, it's too large to convert to i64.
522 #[cfg(target_word_size = "32")]
524 fn to_u64(&self) -> Option<u64> {
525 match self.data.len() {
527 1 => Some(self.data.as_slice()[0] as u64),
529 Some(BigDigit::to_uint(self.data.as_slice()[1], self.data.as_slice()[0]) as u64)
532 let n_lo = BigDigit::to_uint(self.data.as_slice()[1], self.data.as_slice()[0]) as
534 let n_hi = self.data.as_slice()[2] as u64;
535 Some((n_hi << 32) + n_lo)
538 let n_lo = BigDigit::to_uint(self.data.as_slice()[1], self.data.as_slice()[0])
540 let n_hi = BigDigit::to_uint(self.data.as_slice()[3], self.data.as_slice()[2])
542 Some((n_hi << 32) + n_lo)
548 #[cfg(target_word_size = "64")]
550 fn to_u64(&self) -> Option<u64> {
551 match self.data.len() {
553 1 => Some(self.data.as_slice()[0] as u64),
554 2 => Some(BigDigit::to_uint(self.data.as_slice()[1], self.data.as_slice()[0]) as u64),
560 impl FromPrimitive for BigUint {
562 fn from_i64(n: i64) -> Option<BigUint> {
564 FromPrimitive::from_u64(n as u64)
572 #[cfg(target_word_size = "32")]
574 fn from_u64(n: u64) -> Option<BigUint> {
575 let n_lo = (n & 0x0000_0000_FFFF_FFFF) as uint;
576 let n_hi = (n >> 32) as uint;
578 let n = match (BigDigit::from_uint(n_hi), BigDigit::from_uint(n_lo)) {
579 ((0, 0), (0, 0)) => Zero::zero(),
580 ((0, 0), (0, n0)) => BigUint::new(vec!(n0)),
581 ((0, 0), (n1, n0)) => BigUint::new(vec!(n0, n1)),
582 ((0, n2), (n1, n0)) => BigUint::new(vec!(n0, n1, n2)),
583 ((n3, n2), (n1, n0)) => BigUint::new(vec!(n0, n1, n2, n3)),
588 #[cfg(target_word_size = "64")]
590 fn from_u64(n: u64) -> Option<BigUint> {
591 let n = match BigDigit::from_uint(n as uint) {
592 (0, 0) => Zero::zero(),
593 (0, n0) => BigUint::new(vec!(n0)),
594 (n1, n0) => BigUint::new(vec!(n0, n1))
600 /// A generic trait for converting a value to a `BigUint`.
601 pub trait ToBigUint {
602 /// Converts the value of `self` to a `BigUint`.
603 fn to_biguint(&self) -> Option<BigUint>;
606 impl ToBigUint for BigInt {
608 fn to_biguint(&self) -> Option<BigUint> {
609 if self.sign == Plus {
610 Some(self.data.clone())
611 } else if self.sign == Zero {
619 impl ToBigUint for BigUint {
621 fn to_biguint(&self) -> Option<BigUint> {
626 macro_rules! impl_to_biguint(
627 ($T:ty, $from_ty:path) => {
628 impl ToBigUint for $T {
630 fn to_biguint(&self) -> Option<BigUint> {
637 impl_to_biguint!(int, FromPrimitive::from_int)
638 impl_to_biguint!(i8, FromPrimitive::from_i8)
639 impl_to_biguint!(i16, FromPrimitive::from_i16)
640 impl_to_biguint!(i32, FromPrimitive::from_i32)
641 impl_to_biguint!(i64, FromPrimitive::from_i64)
642 impl_to_biguint!(uint, FromPrimitive::from_uint)
643 impl_to_biguint!(u8, FromPrimitive::from_u8)
644 impl_to_biguint!(u16, FromPrimitive::from_u16)
645 impl_to_biguint!(u32, FromPrimitive::from_u32)
646 impl_to_biguint!(u64, FromPrimitive::from_u64)
648 impl ToStrRadix for BigUint {
649 fn to_str_radix(&self, radix: uint) -> ~str {
650 assert!(1 < radix && radix <= 16);
651 let (base, max_len) = get_radix_base(radix);
652 if base == BigDigit::base {
653 return fill_concat(self.data.as_slice(), radix, max_len)
655 return fill_concat(convert_base(self, base).as_slice(), radix, max_len);
657 fn convert_base(n: &BigUint, base: uint) -> Vec<BigDigit> {
658 let divider = FromPrimitive::from_uint(base).unwrap();
659 let mut result = Vec::new();
660 let mut m = n.clone();
662 let (d, m0) = m.div_mod_floor(÷r);
663 result.push(m0.to_uint().unwrap() as BigDigit);
667 result.push(m.to_uint().unwrap() as BigDigit);
672 fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> ~str {
673 if v.is_empty() { return ~"0" }
674 let mut s = str::with_capacity(v.len() * l);
675 for n in v.rev_iter() {
676 let ss = (*n as uint).to_str_radix(radix);
677 s.push_str("0".repeat(l - ss.len()));
680 s.trim_left_chars(&'0').to_owned()
685 impl FromStrRadix for BigUint {
686 /// Creates and initializes a `BigUint`.
688 fn from_str_radix(s: &str, radix: uint)
690 BigUint::parse_bytes(s.as_bytes(), radix)
695 /// Creates and initializes a `BigUint`.
697 pub fn new(v: Vec<BigDigit>) -> BigUint {
698 // omit trailing zeros
699 let new_len = v.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1);
701 if new_len == v.len() { return BigUint { data: v }; }
704 return BigUint { data: v };
707 /// Creates and initializes a `BigUint`.
709 pub fn from_slice(slice: &[BigDigit]) -> BigUint {
710 return BigUint::new(Vec::from_slice(slice));
713 /// Creates and initializes a `BigUint`.
714 pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigUint> {
715 let (base, unit_len) = get_radix_base(radix);
716 let base_num = match FromPrimitive::from_uint(base) {
717 Some(base_num) => base_num,
718 None => { return None; }
721 let mut end = buf.len();
722 let mut n: BigUint = Zero::zero();
723 let mut power: BigUint = One::one();
725 let start = cmp::max(end, unit_len) - unit_len;
726 match uint::parse_bytes(buf.slice(start, end), radix) {
728 let d: Option<BigUint> = FromPrimitive::from_uint(d);
731 // FIXME(#6102): Assignment operator for BigInt
736 None => { return None; }
739 None => { return None; }
745 // FIXME(#6050): overloaded operators force moves with generic types
746 // power *= base_num;
747 power = power * base_num;
752 fn shl_unit(&self, n_unit: uint) -> BigUint {
753 if n_unit == 0 || self.is_zero() { return (*self).clone(); }
755 return BigUint::new(vec::append(Vec::from_elem(n_unit, ZERO_BIG_DIGIT),
756 self.data.as_slice()));
760 fn shl_bits(&self, n_bits: uint) -> BigUint {
761 if n_bits == 0 || self.is_zero() { return (*self).clone(); }
764 let mut shifted: Vec<BigDigit> = self.data.iter().map(|elem| {
765 let (hi, lo) = BigDigit::from_uint(
766 (*elem as uint) << n_bits | (carry as uint)
771 if carry != 0 { shifted.push(carry); }
772 return BigUint::new(shifted);
776 fn shr_unit(&self, n_unit: uint) -> BigUint {
777 if n_unit == 0 { return (*self).clone(); }
778 if self.data.len() < n_unit { return Zero::zero(); }
779 return BigUint::from_slice(
780 self.data.slice(n_unit, self.data.len())
785 fn shr_bits(&self, n_bits: uint) -> BigUint {
786 if n_bits == 0 || self.data.is_empty() { return (*self).clone(); }
789 let mut shifted_rev = Vec::with_capacity(self.data.len());
790 for elem in self.data.iter().rev() {
791 shifted_rev.push((*elem >> n_bits) | borrow);
792 borrow = *elem << (BigDigit::bits - n_bits);
794 let shifted = { shifted_rev.reverse(); shifted_rev };
795 return BigUint::new(shifted);
798 /// Determines the fewest bits necessary to express the `BigUint`.
799 pub fn bits(&self) -> uint {
800 if self.is_zero() { return 0; }
801 let zeros = self.data.last().unwrap().leading_zeros();
802 return self.data.len()*BigDigit::bits - (zeros as uint);
806 #[cfg(target_word_size = "32")]
808 fn get_radix_base(radix: uint) -> (uint, uint) {
809 assert!(1 < radix && radix <= 16);
830 #[cfg(target_word_size = "64")]
832 fn get_radix_base(radix: uint) -> (uint, uint) {
833 assert!(1 < radix && radix <= 16);
835 2 => (4294967296, 32),
836 3 => (3486784401, 20),
837 4 => (4294967296, 16),
838 5 => (1220703125, 13),
839 6 => (2176782336, 12),
840 7 => (1977326743, 11),
841 8 => (1073741824, 10),
842 9 => (3486784401, 10),
843 10 => (1000000000, 9),
844 11 => (2357947691, 9),
845 12 => (429981696, 8),
846 13 => (815730721, 8),
847 14 => (1475789056, 8),
848 15 => (2562890625, 8),
849 16 => (4294967296, 8),
854 /// A Sign is a `BigInt`'s composing element.
855 #[deriving(Eq, Clone, Show)]
856 pub enum Sign { Minus, Zero, Plus }
860 fn lt(&self, other: &Sign) -> bool {
861 match self.cmp(other) { Less => true, _ => false}
865 impl TotalEq for Sign {
867 fn equals(&self, other: &Sign) -> bool { *self == *other }
869 impl TotalOrd for Sign {
871 fn cmp(&self, other: &Sign) -> Ordering {
872 match (*self, *other) {
873 (Minus, Minus) | (Zero, Zero) | (Plus, Plus) => Equal,
874 (Minus, Zero) | (Minus, Plus) | (Zero, Plus) => Less,
880 impl Neg<Sign> for Sign {
881 /// Negate Sign value.
883 fn neg(&self) -> Sign {
892 /// A big signed integer type.
901 fn eq(&self, other: &BigInt) -> bool { self.equals(other) }
904 impl TotalEq for BigInt {
906 fn equals(&self, other: &BigInt) -> bool {
907 match self.cmp(other) { Equal => true, _ => false }
911 impl Ord for BigInt {
913 fn lt(&self, other: &BigInt) -> bool {
914 match self.cmp(other) { Less => true, _ => false}
918 impl TotalOrd for BigInt {
920 fn cmp(&self, other: &BigInt) -> Ordering {
921 let scmp = self.sign.cmp(&other.sign);
922 if scmp != Equal { return scmp; }
926 Plus => self.data.cmp(&other.data),
927 Minus => other.data.cmp(&self.data),
932 impl fmt::Show for BigInt {
933 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
934 write!(f.buf, "{}", self.to_str_radix(10))
938 impl FromStr for BigInt {
940 fn from_str(s: &str) -> Option<BigInt> {
941 FromStrRadix::from_str_radix(s, 10)
945 impl Num for BigInt {}
947 impl Shl<uint, BigInt> for BigInt {
949 fn shl(&self, rhs: &uint) -> BigInt {
950 BigInt::from_biguint(self.sign, self.data << *rhs)
954 impl Shr<uint, BigInt> for BigInt {
956 fn shr(&self, rhs: &uint) -> BigInt {
957 BigInt::from_biguint(self.sign, self.data >> *rhs)
961 impl Zero for BigInt {
963 fn zero() -> BigInt {
964 BigInt::from_biguint(Zero, Zero::zero())
968 fn is_zero(&self) -> bool { self.sign == Zero }
971 impl One for BigInt {
974 BigInt::from_biguint(Plus, One::one())
978 impl Signed for BigInt {
980 fn abs(&self) -> BigInt {
982 Plus | Zero => self.clone(),
983 Minus => BigInt::from_biguint(Plus, self.data.clone())
988 fn abs_sub(&self, other: &BigInt) -> BigInt {
989 if *self <= *other { Zero::zero() } else { *self - *other }
993 fn signum(&self) -> BigInt {
995 Plus => BigInt::from_biguint(Plus, One::one()),
996 Minus => BigInt::from_biguint(Minus, One::one()),
997 Zero => Zero::zero(),
1002 fn is_positive(&self) -> bool { self.sign == Plus }
1005 fn is_negative(&self) -> bool { self.sign == Minus }
1008 impl Add<BigInt, BigInt> for BigInt {
1010 fn add(&self, other: &BigInt) -> BigInt {
1011 match (self.sign, other.sign) {
1012 (Zero, _) => other.clone(),
1013 (_, Zero) => self.clone(),
1014 (Plus, Plus) => BigInt::from_biguint(Plus,
1015 self.data + other.data),
1016 (Plus, Minus) => self - (-*other),
1017 (Minus, Plus) => other - (-*self),
1018 (Minus, Minus) => -((-self) + (-*other))
1023 impl Sub<BigInt, BigInt> for BigInt {
1025 fn sub(&self, other: &BigInt) -> BigInt {
1026 match (self.sign, other.sign) {
1027 (Zero, _) => -other,
1028 (_, Zero) => self.clone(),
1029 (Plus, Plus) => match self.data.cmp(&other.data) {
1030 Less => BigInt::from_biguint(Minus, other.data - self.data),
1031 Greater => BigInt::from_biguint(Plus, self.data - other.data),
1032 Equal => Zero::zero()
1034 (Plus, Minus) => self + (-*other),
1035 (Minus, Plus) => -((-self) + *other),
1036 (Minus, Minus) => (-other) - (-*self)
1041 impl Mul<BigInt, BigInt> for BigInt {
1043 fn mul(&self, other: &BigInt) -> BigInt {
1044 match (self.sign, other.sign) {
1045 (Zero, _) | (_, Zero) => Zero::zero(),
1046 (Plus, Plus) | (Minus, Minus) => {
1047 BigInt::from_biguint(Plus, self.data * other.data)
1049 (Plus, Minus) | (Minus, Plus) => {
1050 BigInt::from_biguint(Minus, self.data * other.data)
1056 impl Div<BigInt, BigInt> for BigInt {
1058 fn div(&self, other: &BigInt) -> BigInt {
1059 let (q, _) = self.div_rem(other);
1064 impl Rem<BigInt, BigInt> for BigInt {
1066 fn rem(&self, other: &BigInt) -> BigInt {
1067 let (_, r) = self.div_rem(other);
1072 impl Neg<BigInt> for BigInt {
1074 fn neg(&self) -> BigInt {
1075 BigInt::from_biguint(self.sign.neg(), self.data.clone())
1079 impl CheckedAdd for BigInt {
1081 fn checked_add(&self, v: &BigInt) -> Option<BigInt> {
1082 return Some(self.add(v));
1086 impl CheckedSub for BigInt {
1088 fn checked_sub(&self, v: &BigInt) -> Option<BigInt> {
1089 return Some(self.sub(v));
1093 impl CheckedMul for BigInt {
1095 fn checked_mul(&self, v: &BigInt) -> Option<BigInt> {
1096 return Some(self.mul(v));
1100 impl CheckedDiv for BigInt {
1102 fn checked_div(&self, v: &BigInt) -> Option<BigInt> {
1106 return Some(self.div(v));
1111 impl Integer for BigInt {
1113 fn div_rem(&self, other: &BigInt) -> (BigInt, BigInt) {
1114 // r.sign == self.sign
1115 let (d_ui, r_ui) = self.data.div_mod_floor(&other.data);
1116 let d = BigInt::from_biguint(Plus, d_ui);
1117 let r = BigInt::from_biguint(Plus, r_ui);
1118 match (self.sign, other.sign) {
1119 (_, Zero) => fail!(),
1120 (Plus, Plus) | (Zero, Plus) => ( d, r),
1121 (Plus, Minus) | (Zero, Minus) => (-d, r),
1122 (Minus, Plus) => (-d, -r),
1123 (Minus, Minus) => ( d, -r)
1128 fn div_floor(&self, other: &BigInt) -> BigInt {
1129 let (d, _) = self.div_mod_floor(other);
1134 fn mod_floor(&self, other: &BigInt) -> BigInt {
1135 let (_, m) = self.div_mod_floor(other);
1139 fn div_mod_floor(&self, other: &BigInt) -> (BigInt, BigInt) {
1140 // m.sign == other.sign
1141 let (d_ui, m_ui) = self.data.div_rem(&other.data);
1142 let d = BigInt::from_biguint(Plus, d_ui);
1143 let m = BigInt::from_biguint(Plus, m_ui);
1144 match (self.sign, other.sign) {
1145 (_, Zero) => fail!(),
1146 (Plus, Plus) | (Zero, Plus) => (d, m),
1147 (Plus, Minus) | (Zero, Minus) => if m.is_zero() {
1150 (-d - One::one(), m + *other)
1152 (Minus, Plus) => if m.is_zero() {
1155 (-d - One::one(), other - m)
1157 (Minus, Minus) => (d, -m)
1162 * Calculates the Greatest Common Divisor (GCD) of the number and `other`
1164 * The result is always positive
1167 fn gcd(&self, other: &BigInt) -> BigInt {
1168 BigInt::from_biguint(Plus, self.data.gcd(&other.data))
1172 * Calculates the Lowest Common Multiple (LCM) of the number and `other`
1175 fn lcm(&self, other: &BigInt) -> BigInt {
1176 BigInt::from_biguint(Plus, self.data.lcm(&other.data))
1179 /// Returns `true` if the number can be divided by `other` without leaving a remainder
1181 fn divides(&self, other: &BigInt) -> bool { self.data.divides(&other.data) }
1183 /// Returns `true` if the number is divisible by `2`
1185 fn is_even(&self) -> bool { self.data.is_even() }
1187 /// Returns `true` if the number is not divisible by `2`
1189 fn is_odd(&self) -> bool { self.data.is_odd() }
1192 impl ToPrimitive for BigInt {
1194 fn to_i64(&self) -> Option<i64> {
1196 Plus => self.data.to_i64(),
1199 self.data.to_u64().and_then(|n| {
1200 let m: u64 = 1 << 63;
1214 fn to_u64(&self) -> Option<u64> {
1216 Plus => self.data.to_u64(),
1223 impl FromPrimitive for BigInt {
1225 fn from_i64(n: i64) -> Option<BigInt> {
1227 FromPrimitive::from_u64(n as u64).and_then(|n| {
1228 Some(BigInt::from_biguint(Plus, n))
1231 FromPrimitive::from_u64(u64::MAX - (n as u64) + 1).and_then(
1233 Some(BigInt::from_biguint(Minus, n))
1241 fn from_u64(n: u64) -> Option<BigInt> {
1245 FromPrimitive::from_u64(n).and_then(|n| {
1246 Some(BigInt::from_biguint(Plus, n))
1252 /// A generic trait for converting a value to a `BigInt`.
1253 pub trait ToBigInt {
1254 /// Converts the value of `self` to a `BigInt`.
1255 fn to_bigint(&self) -> Option<BigInt>;
1258 impl ToBigInt for BigInt {
1260 fn to_bigint(&self) -> Option<BigInt> {
1265 impl ToBigInt for BigUint {
1267 fn to_bigint(&self) -> Option<BigInt> {
1271 Some(BigInt { sign: Plus, data: self.clone() })
1276 macro_rules! impl_to_bigint(
1277 ($T:ty, $from_ty:path) => {
1278 impl ToBigInt for $T {
1280 fn to_bigint(&self) -> Option<BigInt> {
1287 impl_to_bigint!(int, FromPrimitive::from_int)
1288 impl_to_bigint!(i8, FromPrimitive::from_i8)
1289 impl_to_bigint!(i16, FromPrimitive::from_i16)
1290 impl_to_bigint!(i32, FromPrimitive::from_i32)
1291 impl_to_bigint!(i64, FromPrimitive::from_i64)
1292 impl_to_bigint!(uint, FromPrimitive::from_uint)
1293 impl_to_bigint!(u8, FromPrimitive::from_u8)
1294 impl_to_bigint!(u16, FromPrimitive::from_u16)
1295 impl_to_bigint!(u32, FromPrimitive::from_u32)
1296 impl_to_bigint!(u64, FromPrimitive::from_u64)
1298 impl ToStrRadix for BigInt {
1300 fn to_str_radix(&self, radix: uint) -> ~str {
1302 Plus => self.data.to_str_radix(radix),
1304 Minus => ~"-" + self.data.to_str_radix(radix)
1309 impl FromStrRadix for BigInt {
1310 /// Creates and initializes a BigInt.
1312 fn from_str_radix(s: &str, radix: uint) -> Option<BigInt> {
1313 BigInt::parse_bytes(s.as_bytes(), radix)
1317 pub trait RandBigInt {
1318 /// Generate a random `BigUint` of the given bit size.
1319 fn gen_biguint(&mut self, bit_size: uint) -> BigUint;
1321 /// Generate a random BigInt of the given bit size.
1322 fn gen_bigint(&mut self, bit_size: uint) -> BigInt;
1324 /// Generate a random `BigUint` less than the given bound. Fails
1325 /// when the bound is zero.
1326 fn gen_biguint_below(&mut self, bound: &BigUint) -> BigUint;
1328 /// Generate a random `BigUint` within the given range. The lower
1329 /// bound is inclusive; the upper bound is exclusive. Fails when
1330 /// the upper bound is not greater than the lower bound.
1331 fn gen_biguint_range(&mut self, lbound: &BigUint, ubound: &BigUint) -> BigUint;
1333 /// Generate a random `BigInt` within the given range. The lower
1334 /// bound is inclusive; the upper bound is exclusive. Fails when
1335 /// the upper bound is not greater than the lower bound.
1336 fn gen_bigint_range(&mut self, lbound: &BigInt, ubound: &BigInt) -> BigInt;
1339 impl<R: Rng> RandBigInt for R {
1340 fn gen_biguint(&mut self, bit_size: uint) -> BigUint {
1341 let (digits, rem) = bit_size.div_rem(&BigDigit::bits);
1342 let mut data = Vec::with_capacity(digits+1);
1343 for _ in range(0, digits) {
1344 data.push(self.gen());
1347 let final_digit: BigDigit = self.gen();
1348 data.push(final_digit >> (BigDigit::bits - rem));
1350 return BigUint::new(data);
1353 fn gen_bigint(&mut self, bit_size: uint) -> BigInt {
1354 // Generate a random BigUint...
1355 let biguint = self.gen_biguint(bit_size);
1356 // ...and then randomly assign it a Sign...
1357 let sign = if biguint.is_zero() {
1358 // ...except that if the BigUint is zero, we need to try
1359 // again with probability 0.5. This is because otherwise,
1360 // the probability of generating a zero BigInt would be
1361 // double that of any other number.
1363 return self.gen_bigint(bit_size);
1367 } else if self.gen() {
1372 return BigInt::from_biguint(sign, biguint);
1375 fn gen_biguint_below(&mut self, bound: &BigUint) -> BigUint {
1376 assert!(!bound.is_zero());
1377 let bits = bound.bits();
1379 let n = self.gen_biguint(bits);
1380 if n < *bound { return n; }
1384 fn gen_biguint_range(&mut self,
1388 assert!(*lbound < *ubound);
1389 return *lbound + self.gen_biguint_below(&(*ubound - *lbound));
1392 fn gen_bigint_range(&mut self,
1396 assert!(*lbound < *ubound);
1397 let delta = (*ubound - *lbound).to_biguint().unwrap();
1398 return *lbound + self.gen_biguint_below(&delta).to_bigint().unwrap();
1403 /// Creates and initializes a BigInt.
1405 pub fn new(sign: Sign, v: Vec<BigDigit>) -> BigInt {
1406 BigInt::from_biguint(sign, BigUint::new(v))
1409 /// Creates and initializes a `BigInt`.
1411 pub fn from_biguint(sign: Sign, data: BigUint) -> BigInt {
1412 if sign == Zero || data.is_zero() {
1413 return BigInt { sign: Zero, data: Zero::zero() };
1415 return BigInt { sign: sign, data: data };
1418 /// Creates and initializes a `BigInt`.
1420 pub fn from_slice(sign: Sign, slice: &[BigDigit]) -> BigInt {
1421 BigInt::from_biguint(sign, BigUint::from_slice(slice))
1424 /// Creates and initializes a `BigInt`.
1425 pub fn parse_bytes(buf: &[u8], radix: uint)
1427 if buf.is_empty() { return None; }
1428 let mut sign = Plus;
1430 if buf[0] == ('-' as u8) {
1434 return BigUint::parse_bytes(buf.slice(start, buf.len()), radix)
1435 .map(|bu| BigInt::from_biguint(sign, bu));
1438 /// Converts this `BigInt` into a `BigUint`, if it's not negative.
1440 pub fn to_biguint(&self) -> Option<BigUint> {
1442 Plus => Some(self.data.clone()),
1443 Zero => Some(Zero::zero()),
1452 use super::{BigDigit, BigUint, ToBigUint};
1453 use super::{Plus, BigInt, RandBigInt, ToBigInt};
1455 use std::cmp::{Less, Equal, Greater};
1456 use std::from_str::FromStr;
1458 use std::num::{Zero, One, FromStrRadix, ToStrRadix};
1459 use std::num::{ToPrimitive, FromPrimitive};
1460 use std::num::CheckedDiv;
1461 use rand::{task_rng};
1465 fn test_from_slice() {
1466 fn check(slice: &[BigDigit], data: &[BigDigit]) {
1467 assert!(data == BigUint::from_slice(slice).data.as_slice());
1470 check([0, 0, 0], []);
1471 check([1, 2, 0, 0], [1, 2]);
1472 check([0, 0, 1, 2], [0, 0, 1, 2]);
1473 check([0, 0, 1, 2, 0, 0], [0, 0, 1, 2]);
1479 let data: Vec<BigUint> = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1] ]
1480 .iter().map(|v| BigUint::from_slice(*v)).collect();
1481 for (i, ni) in data.iter().enumerate() {
1482 for (j0, nj) in data.slice(i, data.len()).iter().enumerate() {
1485 assert_eq!(ni.cmp(nj), Equal);
1486 assert_eq!(nj.cmp(ni), Equal);
1488 assert!(!(ni != nj));
1491 assert!(!(ni < nj));
1492 assert!(!(ni > nj));
1494 assert_eq!(ni.cmp(nj), Less);
1495 assert_eq!(nj.cmp(ni), Greater);
1497 assert!(!(ni == nj));
1501 assert!(!(ni >= nj));
1503 assert!(!(ni > nj));
1505 assert!(!(nj <= ni));
1507 assert!(!(nj < ni));
1516 fn check(left: &[BigDigit],
1518 expected: &[BigDigit]) {
1519 assert_eq!(BigUint::from_slice(left) & BigUint::from_slice(right),
1520 BigUint::from_slice(expected));
1523 check([268, 482, 17],
1530 fn check(left: &[BigDigit],
1532 expected: &[BigDigit]) {
1533 assert_eq!(BigUint::from_slice(left) | BigUint::from_slice(right),
1534 BigUint::from_slice(expected));
1537 check([268, 482, 17],
1544 fn check(left: &[BigDigit],
1546 expected: &[BigDigit]) {
1547 assert_eq!(BigUint::from_slice(left) ^ BigUint::from_slice(right),
1548 BigUint::from_slice(expected));
1551 check([268, 482, 17],
1558 fn check(s: &str, shift: uint, ans: &str) {
1559 let opt_biguint: Option<BigUint> = FromStrRadix::from_str_radix(s, 16);
1560 let bu = (opt_biguint.unwrap() << shift).to_str_radix(16);
1561 assert_eq!(bu.as_slice(), ans);
1567 check("1" + "0000" + "0000" + "0000" + "0001" + "0000" + "0000" + "0000" + "0001", 3,
1568 "8" + "0000" + "0000" + "0000" + "0008" + "0000" + "0000" + "0000" + "0008");
1569 check("1" + "0000" + "0001" + "0000" + "0001", 2,
1570 "4" + "0000" + "0004" + "0000" + "0004");
1571 check("1" + "0001" + "0001", 1,
1572 "2" + "0002" + "0002");
1574 check("" + "4000" + "0000" + "0000" + "0000", 3,
1575 "2" + "0000" + "0000" + "0000" + "0000");
1576 check("" + "4000" + "0000", 2,
1577 "1" + "0000" + "0000");
1578 check("" + "4000", 2,
1581 check("" + "4000" + "0000" + "0000" + "0000", 67,
1582 "2" + "0000" + "0000" + "0000" + "0000" + "0000" + "0000" + "0000" + "0000");
1583 check("" + "4000" + "0000", 35,
1584 "2" + "0000" + "0000" + "0000" + "0000");
1585 check("" + "4000", 19,
1586 "2" + "0000" + "0000");
1588 check("" + "fedc" + "ba98" + "7654" + "3210" + "fedc" + "ba98" + "7654" + "3210", 4,
1589 "f" + "edcb" + "a987" + "6543" + "210f" + "edcb" + "a987" + "6543" + "2100");
1590 check("88887777666655554444333322221111", 16,
1591 "888877776666555544443333222211110000");
1596 fn check(s: &str, shift: uint, ans: &str) {
1597 let opt_biguint: Option<BigUint> =
1598 FromStrRadix::from_str_radix(s, 16);
1599 let bu = (opt_biguint.unwrap() >> shift).to_str_radix(16);
1600 assert_eq!(bu.as_slice(), ans);
1606 check("1" + "0000" + "0000" + "0000" + "0001" + "0000" + "0000" + "0000" + "0001", 3,
1607 "" + "2000" + "0000" + "0000" + "0000" + "2000" + "0000" + "0000" + "0000");
1608 check("1" + "0000" + "0001" + "0000" + "0001", 2,
1609 "" + "4000" + "0000" + "4000" + "0000");
1610 check("1" + "0001" + "0001", 1,
1611 "" + "8000" + "8000");
1613 check("2" + "0000" + "0000" + "0000" + "0001" + "0000" + "0000" + "0000" + "0001", 67,
1614 "" + "4000" + "0000" + "0000" + "0000");
1615 check("2" + "0000" + "0001" + "0000" + "0001", 35,
1616 "" + "4000" + "0000");
1617 check("2" + "0001" + "0001", 19,
1620 check("1" + "0000" + "0000" + "0000" + "0000", 1,
1621 "" + "8000" + "0000" + "0000" + "0000");
1622 check("1" + "0000" + "0000", 1,
1623 "" + "8000" + "0000");
1624 check("1" + "0000", 1,
1626 check("f" + "edcb" + "a987" + "6543" + "210f" + "edcb" + "a987" + "6543" + "2100", 4,
1627 "" + "fedc" + "ba98" + "7654" + "3210" + "fedc" + "ba98" + "7654" + "3210");
1629 check("888877776666555544443333222211110000", 16,
1630 "88887777666655554444333322221111");
1633 #[cfg(target_word_size = "32")]
1635 fn test_convert_i64() {
1636 fn check(b1: BigUint, i: i64) {
1637 let b2: BigUint = FromPrimitive::from_i64(i).unwrap();
1639 assert!(b1.to_i64().unwrap() == i);
1642 check(Zero::zero(), 0);
1643 check(One::one(), 1);
1644 check(i64::MAX.to_biguint().unwrap(), i64::MAX);
1646 check(BigUint::new(vec!( )), 0);
1647 check(BigUint::new(vec!( 1 )), (1 << (0*BigDigit::bits)));
1648 check(BigUint::new(vec!(-1 )), (1 << (1*BigDigit::bits)) - 1);
1649 check(BigUint::new(vec!( 0, 1 )), (1 << (1*BigDigit::bits)));
1650 check(BigUint::new(vec!(-1, -1 )), (1 << (2*BigDigit::bits)) - 1);
1651 check(BigUint::new(vec!( 0, 0, 1 )), (1 << (2*BigDigit::bits)));
1652 check(BigUint::new(vec!(-1, -1, -1 )), (1 << (3*BigDigit::bits)) - 1);
1653 check(BigUint::new(vec!( 0, 0, 0, 1 )), (1 << (3*BigDigit::bits)));
1654 check(BigUint::new(vec!(-1, -1, -1, -1 >> 1)), i64::MAX);
1656 assert_eq!(i64::MIN.to_biguint(), None);
1657 assert_eq!(BigUint::new(vec!(-1, -1, -1, -1 )).to_i64(), None);
1658 assert_eq!(BigUint::new(vec!( 0, 0, 0, 0, 1)).to_i64(), None);
1659 assert_eq!(BigUint::new(vec!(-1, -1, -1, -1, -1)).to_i64(), None);
1662 #[cfg(target_word_size = "64")]
1664 fn test_convert_i64() {
1665 fn check(b1: BigUint, i: i64) {
1666 let b2: BigUint = FromPrimitive::from_i64(i).unwrap();
1668 assert!(b1.to_i64().unwrap() == i);
1671 check(Zero::zero(), 0);
1672 check(One::one(), 1);
1673 check(i64::MAX.to_biguint().unwrap(), i64::MAX);
1675 check(BigUint::new(vec!( )), 0);
1676 check(BigUint::new(vec!( 1 )), (1 << (0*BigDigit::bits)));
1677 check(BigUint::new(vec!(-1 )), (1 << (1*BigDigit::bits)) - 1);
1678 check(BigUint::new(vec!( 0, 1 )), (1 << (1*BigDigit::bits)));
1679 check(BigUint::new(vec!(-1, -1 >> 1)), i64::MAX);
1681 assert_eq!(i64::MIN.to_biguint(), None);
1682 assert_eq!(BigUint::new(vec!(-1, -1 )).to_i64(), None);
1683 assert_eq!(BigUint::new(vec!( 0, 0, 1)).to_i64(), None);
1684 assert_eq!(BigUint::new(vec!(-1, -1, -1)).to_i64(), None);
1687 #[cfg(target_word_size = "32")]
1689 fn test_convert_u64() {
1690 fn check(b1: BigUint, u: u64) {
1691 let b2: BigUint = FromPrimitive::from_u64(u).unwrap();
1693 assert!(b1.to_u64().unwrap() == u);
1696 check(Zero::zero(), 0);
1697 check(One::one(), 1);
1698 check(u64::MIN.to_biguint().unwrap(), u64::MIN);
1699 check(u64::MAX.to_biguint().unwrap(), u64::MAX);
1701 check(BigUint::new(vec!( )), 0);
1702 check(BigUint::new(vec!( 1 )), (1 << (0*BigDigit::bits)));
1703 check(BigUint::new(vec!(-1 )), (1 << (1*BigDigit::bits)) - 1);
1704 check(BigUint::new(vec!( 0, 1 )), (1 << (1*BigDigit::bits)));
1705 check(BigUint::new(vec!(-1, -1 )), (1 << (2*BigDigit::bits)) - 1);
1706 check(BigUint::new(vec!( 0, 0, 1 )), (1 << (2*BigDigit::bits)));
1707 check(BigUint::new(vec!(-1, -1, -1 )), (1 << (3*BigDigit::bits)) - 1);
1708 check(BigUint::new(vec!( 0, 0, 0, 1)), (1 << (3*BigDigit::bits)));
1709 check(BigUint::new(vec!(-1, -1, -1, -1)), u64::MAX);
1711 assert_eq!(BigUint::new(vec!( 0, 0, 0, 0, 1)).to_u64(), None);
1712 assert_eq!(BigUint::new(vec!(-1, -1, -1, -1, -1)).to_u64(), None);
1715 #[cfg(target_word_size = "64")]
1717 fn test_convert_u64() {
1718 fn check(b1: BigUint, u: u64) {
1719 let b2: BigUint = FromPrimitive::from_u64(u).unwrap();
1721 assert!(b1.to_u64().unwrap() == u);
1724 check(Zero::zero(), 0);
1725 check(One::one(), 1);
1726 check(u64::MIN.to_biguint().unwrap(), u64::MIN);
1727 check(u64::MAX.to_biguint().unwrap(), u64::MAX);
1729 check(BigUint::new(vec!( )), 0);
1730 check(BigUint::new(vec!( 1 )), (1 << (0*BigDigit::bits)));
1731 check(BigUint::new(vec!(-1 )), (1 << (1*BigDigit::bits)) - 1);
1732 check(BigUint::new(vec!( 0, 1)), (1 << (1*BigDigit::bits)));
1733 check(BigUint::new(vec!(-1, -1)), u64::MAX);
1735 assert_eq!(BigUint::new(vec!( 0, 0, 1)).to_u64(), None);
1736 assert_eq!(BigUint::new(vec!(-1, -1, -1)).to_u64(), None);
1740 fn test_convert_to_bigint() {
1741 fn check(n: BigUint, ans: BigInt) {
1742 assert_eq!(n.to_bigint().unwrap(), ans);
1743 assert_eq!(n.to_bigint().unwrap().to_biguint().unwrap(), n);
1745 check(Zero::zero(), Zero::zero());
1746 check(BigUint::new(vec!(1,2,3)),
1747 BigInt::from_biguint(Plus, BigUint::new(vec!(1,2,3))));
1750 static sum_triples: &'static [(&'static [BigDigit],
1751 &'static [BigDigit],
1752 &'static [BigDigit])] = &[
1754 (&[], &[ 1], &[ 1]),
1755 (&[ 1], &[ 1], &[ 2]),
1756 (&[ 1], &[ 1, 1], &[ 2, 1]),
1757 (&[ 1], &[-1], &[ 0, 1]),
1758 (&[ 1], &[-1, -1], &[ 0, 0, 1]),
1759 (&[-1, -1], &[-1, -1], &[-2, -1, 1]),
1760 (&[ 1, 1, 1], &[-1, -1], &[ 0, 1, 2]),
1761 (&[ 2, 2, 1], &[-1, -2], &[ 1, 1, 2])
1766 for elm in sum_triples.iter() {
1767 let (a_vec, b_vec, c_vec) = *elm;
1768 let a = BigUint::from_slice(a_vec);
1769 let b = BigUint::from_slice(b_vec);
1770 let c = BigUint::from_slice(c_vec);
1772 assert!(a + b == c);
1773 assert!(b + a == c);
1779 for elm in sum_triples.iter() {
1780 let (a_vec, b_vec, c_vec) = *elm;
1781 let a = BigUint::from_slice(a_vec);
1782 let b = BigUint::from_slice(b_vec);
1783 let c = BigUint::from_slice(c_vec);
1785 assert!(c - a == b);
1786 assert!(c - b == a);
1790 static mul_triples: &'static [(&'static [BigDigit],
1791 &'static [BigDigit],
1792 &'static [BigDigit])] = &[
1796 (&[ 1], &[ 1], &[1]),
1797 (&[ 2], &[ 3], &[ 6]),
1798 (&[ 1], &[ 1, 1, 1], &[1, 1, 1]),
1799 (&[ 1, 2, 3], &[ 3], &[ 3, 6, 9]),
1800 (&[ 1, 1, 1], &[-1], &[-1, -1, -1]),
1801 (&[ 1, 2, 3], &[-1], &[-1, -2, -2, 2]),
1802 (&[ 1, 2, 3, 4], &[-1], &[-1, -2, -2, -2, 3]),
1803 (&[-1], &[-1], &[ 1, -2]),
1804 (&[-1, -1], &[-1], &[ 1, -1, -2]),
1805 (&[-1, -1, -1], &[-1], &[ 1, -1, -1, -2]),
1806 (&[-1, -1, -1, -1], &[-1], &[ 1, -1, -1, -1, -2]),
1807 (&[-1/2 + 1], &[ 2], &[ 0, 1]),
1808 (&[0, -1/2 + 1], &[ 2], &[ 0, 0, 1]),
1809 (&[ 1, 2], &[ 1, 2, 3], &[1, 4, 7, 6]),
1810 (&[-1, -1], &[-1, -1, -1], &[1, 0, -1, -2, -1]),
1811 (&[-1, -1, -1], &[-1, -1, -1, -1], &[1, 0, 0, -1, -2, -1, -1]),
1812 (&[ 0, 0, 1], &[ 1, 2, 3], &[0, 0, 1, 2, 3]),
1813 (&[ 0, 0, 1], &[ 0, 0, 0, 1], &[0, 0, 0, 0, 0, 1])
1816 static div_rem_quadruples: &'static [(&'static [BigDigit],
1817 &'static [BigDigit],
1818 &'static [BigDigit],
1819 &'static [BigDigit])]
1821 (&[ 1], &[ 2], &[], &[1]),
1822 (&[ 1, 1], &[ 2], &[-1/2+1], &[1]),
1823 (&[ 1, 1, 1], &[ 2], &[-1/2+1, -1/2+1], &[1]),
1824 (&[ 0, 1], &[-1], &[1], &[1]),
1825 (&[-1, -1], &[-2], &[2, 1], &[3])
1830 for elm in mul_triples.iter() {
1831 let (a_vec, b_vec, c_vec) = *elm;
1832 let a = BigUint::from_slice(a_vec);
1833 let b = BigUint::from_slice(b_vec);
1834 let c = BigUint::from_slice(c_vec);
1836 assert!(a * b == c);
1837 assert!(b * a == c);
1840 for elm in div_rem_quadruples.iter() {
1841 let (a_vec, b_vec, c_vec, d_vec) = *elm;
1842 let a = BigUint::from_slice(a_vec);
1843 let b = BigUint::from_slice(b_vec);
1844 let c = BigUint::from_slice(c_vec);
1845 let d = BigUint::from_slice(d_vec);
1847 assert!(a == b * c + d);
1848 assert!(a == c * b + d);
1854 for elm in mul_triples.iter() {
1855 let (a_vec, b_vec, c_vec) = *elm;
1856 let a = BigUint::from_slice(a_vec);
1857 let b = BigUint::from_slice(b_vec);
1858 let c = BigUint::from_slice(c_vec);
1861 assert_eq!(c.div_rem(&a), (b.clone(), Zero::zero()));
1864 assert_eq!(c.div_rem(&b), (a.clone(), Zero::zero()));
1868 for elm in div_rem_quadruples.iter() {
1869 let (a_vec, b_vec, c_vec, d_vec) = *elm;
1870 let a = BigUint::from_slice(a_vec);
1871 let b = BigUint::from_slice(b_vec);
1872 let c = BigUint::from_slice(c_vec);
1873 let d = BigUint::from_slice(d_vec);
1875 if !b.is_zero() { assert!(a.div_rem(&b) == (c, d)); }
1880 fn test_checked_add() {
1881 for elm in sum_triples.iter() {
1882 let (aVec, bVec, cVec) = *elm;
1883 let a = BigUint::from_slice(aVec);
1884 let b = BigUint::from_slice(bVec);
1885 let c = BigUint::from_slice(cVec);
1887 assert!(a.checked_add(&b).unwrap() == c);
1888 assert!(b.checked_add(&a).unwrap() == c);
1893 fn test_checked_sub() {
1894 for elm in sum_triples.iter() {
1895 let (aVec, bVec, cVec) = *elm;
1896 let a = BigUint::from_slice(aVec);
1897 let b = BigUint::from_slice(bVec);
1898 let c = BigUint::from_slice(cVec);
1900 assert!(c.checked_sub(&a).unwrap() == b);
1901 assert!(c.checked_sub(&b).unwrap() == a);
1904 assert!(a.checked_sub(&c).is_none());
1907 assert!(b.checked_sub(&c).is_none());
1913 fn test_checked_mul() {
1914 for elm in mul_triples.iter() {
1915 let (aVec, bVec, cVec) = *elm;
1916 let a = BigUint::from_slice(aVec);
1917 let b = BigUint::from_slice(bVec);
1918 let c = BigUint::from_slice(cVec);
1920 assert!(a.checked_mul(&b).unwrap() == c);
1921 assert!(b.checked_mul(&a).unwrap() == c);
1924 for elm in div_rem_quadruples.iter() {
1925 let (aVec, bVec, cVec, dVec) = *elm;
1926 let a = BigUint::from_slice(aVec);
1927 let b = BigUint::from_slice(bVec);
1928 let c = BigUint::from_slice(cVec);
1929 let d = BigUint::from_slice(dVec);
1931 assert!(a == b.checked_mul(&c).unwrap() + d);
1932 assert!(a == c.checked_mul(&b).unwrap() + d);
1937 fn test_checked_div() {
1938 for elm in mul_triples.iter() {
1939 let (aVec, bVec, cVec) = *elm;
1940 let a = BigUint::from_slice(aVec);
1941 let b = BigUint::from_slice(bVec);
1942 let c = BigUint::from_slice(cVec);
1945 assert!(c.checked_div(&a).unwrap() == b);
1948 assert!(c.checked_div(&b).unwrap() == a);
1951 assert!(c.checked_div(&Zero::zero()).is_none());
1957 fn check(a: uint, b: uint, c: uint) {
1958 let big_a: BigUint = FromPrimitive::from_uint(a).unwrap();
1959 let big_b: BigUint = FromPrimitive::from_uint(b).unwrap();
1960 let big_c: BigUint = FromPrimitive::from_uint(c).unwrap();
1962 assert_eq!(big_a.gcd(&big_b), big_c);
1974 fn check(a: uint, b: uint, c: uint) {
1975 let big_a: BigUint = FromPrimitive::from_uint(a).unwrap();
1976 let big_b: BigUint = FromPrimitive::from_uint(b).unwrap();
1977 let big_c: BigUint = FromPrimitive::from_uint(c).unwrap();
1979 assert_eq!(big_a.lcm(&big_b), big_c);
1987 check(99, 17, 1683);
1992 let one: BigUint = FromStr::from_str("1").unwrap();
1993 let two: BigUint = FromStr::from_str("2").unwrap();
1994 let thousand: BigUint = FromStr::from_str("1000").unwrap();
1995 let big: BigUint = FromStr::from_str("1000000000000000000000").unwrap();
1996 let bigger: BigUint = FromStr::from_str("1000000000000000000001").unwrap();
1997 assert!(one.is_odd());
1998 assert!(two.is_even());
1999 assert!(thousand.is_even());
2000 assert!(big.is_even());
2001 assert!(bigger.is_odd());
2002 assert!((one << 64).is_even());
2003 assert!(((one << 64) + one).is_odd());
2006 fn to_str_pairs() -> Vec<(BigUint, Vec<(uint, ~str)>)> {
2007 let bits = BigDigit::bits;
2008 vec!(( Zero::zero(), vec!(
2009 (2, ~"0"), (3, ~"0")
2010 )), ( BigUint::from_slice([ 0xff ]), vec!(
2026 )), ( BigUint::from_slice([ 0xfff ]), vec!(
2027 (2, ~"111111111111"),
2030 )), ( BigUint::from_slice([ 1, 2 ]), vec!(
2033 "0".repeat(bits - 1) + "1"),
2036 "0".repeat(bits / 2 - 1) + "1"),
2038 32 => ~"8589934593", 16 => ~"131073", _ => fail!()
2042 "0".repeat(bits / 4 - 1) + "1")
2043 )), ( BigUint::from_slice([ 1, 2, 3 ]), vec!(
2046 "0".repeat(bits - 2) + "10" +
2047 "0".repeat(bits - 1) + "1"),
2050 "0".repeat(bits / 2 - 1) + "2" +
2051 "0".repeat(bits / 2 - 1) + "1"),
2053 32 => ~"55340232229718589441",
2054 16 => ~"12885032961",
2058 "0".repeat(bits / 4 - 1) + "2" +
2059 "0".repeat(bits / 4 - 1) + "1")
2064 fn test_to_str_radix() {
2065 let r = to_str_pairs();
2066 for num_pair in r.iter() {
2067 let &(ref n, ref rs) = num_pair;
2068 for str_pair in rs.iter() {
2069 let &(ref radix, ref str) = str_pair;
2070 assert_eq!(&n.to_str_radix(*radix), str);
2076 fn test_from_str_radix() {
2077 let r = to_str_pairs();
2078 for num_pair in r.iter() {
2079 let &(ref n, ref rs) = num_pair;
2080 for str_pair in rs.iter() {
2081 let &(ref radix, ref str) = str_pair;
2082 assert_eq!(n, &FromStrRadix::from_str_radix(*str, *radix).unwrap());
2086 let zed: Option<BigUint> = FromStrRadix::from_str_radix("Z", 10);
2087 assert_eq!(zed, None);
2088 let blank: Option<BigUint> = FromStrRadix::from_str_radix("_", 2);
2089 assert_eq!(blank, None);
2090 let minus_one: Option<BigUint> = FromStrRadix::from_str_radix("-1",
2092 assert_eq!(minus_one, None);
2097 fn factor(n: uint) -> BigUint {
2098 let mut f: BigUint = One::one();
2099 for i in range(2, n + 1) {
2100 // FIXME(#6102): Assignment operator for BigInt causes ICE
2101 // f *= FromPrimitive::from_uint(i);
2102 f = f * FromPrimitive::from_uint(i).unwrap();
2107 fn check(n: uint, s: &str) {
2109 let ans = match FromStrRadix::from_str_radix(s, 10) {
2110 Some(x) => x, None => fail!()
2116 check(10, "3628800");
2117 check(20, "2432902008176640000");
2118 check(30, "265252859812191058636308480000000");
2123 assert_eq!(BigUint::new(vec!(0,0,0,0)).bits(), 0);
2124 let n: BigUint = FromPrimitive::from_uint(0).unwrap();
2125 assert_eq!(n.bits(), 0);
2126 let n: BigUint = FromPrimitive::from_uint(1).unwrap();
2127 assert_eq!(n.bits(), 1);
2128 let n: BigUint = FromPrimitive::from_uint(3).unwrap();
2129 assert_eq!(n.bits(), 2);
2130 let n: BigUint = FromStrRadix::from_str_radix("4000000000", 16).unwrap();
2131 assert_eq!(n.bits(), 39);
2132 let one: BigUint = One::one();
2133 assert_eq!((one << 426).bits(), 427);
2138 let mut rng = task_rng();
2139 let _n: BigUint = rng.gen_biguint(137);
2140 assert!(rng.gen_biguint(0).is_zero());
2144 fn test_rand_range() {
2145 let mut rng = task_rng();
2147 for _ in range(0, 10) {
2148 assert_eq!(rng.gen_bigint_range(&FromPrimitive::from_uint(236).unwrap(),
2149 &FromPrimitive::from_uint(237).unwrap()),
2150 FromPrimitive::from_uint(236).unwrap());
2153 let l = FromPrimitive::from_uint(403469000 + 2352).unwrap();
2154 let u = FromPrimitive::from_uint(403469000 + 3513).unwrap();
2155 for _ in range(0, 1000) {
2156 let n: BigUint = rng.gen_biguint_below(&u);
2159 let n: BigUint = rng.gen_biguint_range(&l, &u);
2167 fn test_zero_rand_range() {
2168 task_rng().gen_biguint_range(&FromPrimitive::from_uint(54).unwrap(),
2169 &FromPrimitive::from_uint(54).unwrap());
2174 fn test_negative_rand_range() {
2175 let mut rng = task_rng();
2176 let l = FromPrimitive::from_uint(2352).unwrap();
2177 let u = FromPrimitive::from_uint(3513).unwrap();
2178 // Switching u and l should fail:
2179 let _n: BigUint = rng.gen_biguint_range(&u, &l);
2186 use super::{BigDigit, BigUint, ToBigUint};
2187 use super::{Sign, Minus, Zero, Plus, BigInt, RandBigInt, ToBigInt};
2189 use std::cmp::{Less, Equal, Greater};
2191 use std::num::CheckedDiv;
2192 use std::num::{Zero, One, FromStrRadix, ToStrRadix};
2193 use std::num::{ToPrimitive, FromPrimitive};
2194 use rand::{task_rng};
2198 fn test_from_biguint() {
2199 fn check(inp_s: Sign, inp_n: uint, ans_s: Sign, ans_n: uint) {
2200 let inp = BigInt::from_biguint(inp_s, FromPrimitive::from_uint(inp_n).unwrap());
2201 let ans = BigInt { sign: ans_s, data: FromPrimitive::from_uint(ans_n).unwrap()};
2202 assert_eq!(inp, ans);
2204 check(Plus, 1, Plus, 1);
2205 check(Plus, 0, Zero, 0);
2206 check(Minus, 1, Minus, 1);
2207 check(Zero, 1, Zero, 0);
2212 let vs = [ &[2 as BigDigit], &[1, 1], &[2, 1], &[1, 1, 1] ];
2213 let mut nums = Vec::new();
2214 for s in vs.rev_iter() {
2215 nums.push(BigInt::from_slice(Minus, *s));
2217 nums.push(Zero::zero());
2218 nums.extend(&mut vs.iter().map(|s| BigInt::from_slice(Plus, *s)));
2220 for (i, ni) in nums.iter().enumerate() {
2221 for (j0, nj) in nums.slice(i, nums.len()).iter().enumerate() {
2224 assert_eq!(ni.cmp(nj), Equal);
2225 assert_eq!(nj.cmp(ni), Equal);
2227 assert!(!(ni != nj));
2230 assert!(!(ni < nj));
2231 assert!(!(ni > nj));
2233 assert_eq!(ni.cmp(nj), Less);
2234 assert_eq!(nj.cmp(ni), Greater);
2236 assert!(!(ni == nj));
2240 assert!(!(ni >= nj));
2242 assert!(!(ni > nj));
2244 assert!(!(nj <= ni));
2246 assert!(!(nj < ni));
2254 fn test_convert_i64() {
2255 fn check(b1: BigInt, i: i64) {
2256 let b2: BigInt = FromPrimitive::from_i64(i).unwrap();
2258 assert!(b1.to_i64().unwrap() == i);
2261 check(Zero::zero(), 0);
2262 check(One::one(), 1);
2263 check(i64::MIN.to_bigint().unwrap(), i64::MIN);
2264 check(i64::MAX.to_bigint().unwrap(), i64::MAX);
2267 (i64::MAX as u64 + 1).to_bigint().unwrap().to_i64(),
2271 BigInt::from_biguint(Plus, BigUint::new(vec!(1, 2, 3, 4, 5))).to_i64(),
2275 BigInt::from_biguint(Minus, BigUint::new(vec!(1,0,0,1<<(BigDigit::bits-1)))).to_i64(),
2279 BigInt::from_biguint(Minus, BigUint::new(vec!(1, 2, 3, 4, 5))).to_i64(),
2284 fn test_convert_u64() {
2285 fn check(b1: BigInt, u: u64) {
2286 let b2: BigInt = FromPrimitive::from_u64(u).unwrap();
2288 assert!(b1.to_u64().unwrap() == u);
2291 check(Zero::zero(), 0);
2292 check(One::one(), 1);
2293 check(u64::MIN.to_bigint().unwrap(), u64::MIN);
2294 check(u64::MAX.to_bigint().unwrap(), u64::MAX);
2297 BigInt::from_biguint(Plus, BigUint::new(vec!(1, 2, 3, 4, 5))).to_u64(),
2300 let max_value: BigUint = FromPrimitive::from_u64(u64::MAX).unwrap();
2301 assert_eq!(BigInt::from_biguint(Minus, max_value).to_u64(), None);
2302 assert_eq!(BigInt::from_biguint(Minus, BigUint::new(vec!(1, 2, 3, 4, 5))).to_u64(), None);
2306 fn test_convert_to_biguint() {
2307 fn check(n: BigInt, ans_1: BigUint) {
2308 assert_eq!(n.to_biguint().unwrap(), ans_1);
2309 assert_eq!(n.to_biguint().unwrap().to_bigint().unwrap(), n);
2311 let zero: BigInt = Zero::zero();
2312 let unsigned_zero: BigUint = Zero::zero();
2313 let positive = BigInt::from_biguint(
2314 Plus, BigUint::new(vec!(1,2,3)));
2315 let negative = -positive;
2317 check(zero, unsigned_zero);
2318 check(positive, BigUint::new(vec!(1,2,3)));
2320 assert_eq!(negative.to_biguint(), None);
2323 static sum_triples: &'static [(&'static [BigDigit],
2324 &'static [BigDigit],
2325 &'static [BigDigit])] = &[
2327 (&[], &[ 1], &[ 1]),
2328 (&[ 1], &[ 1], &[ 2]),
2329 (&[ 1], &[ 1, 1], &[ 2, 1]),
2330 (&[ 1], &[-1], &[ 0, 1]),
2331 (&[ 1], &[-1, -1], &[ 0, 0, 1]),
2332 (&[-1, -1], &[-1, -1], &[-2, -1, 1]),
2333 (&[ 1, 1, 1], &[-1, -1], &[ 0, 1, 2]),
2334 (&[ 2, 2, 1], &[-1, -2], &[ 1, 1, 2])
2339 for elm in sum_triples.iter() {
2340 let (a_vec, b_vec, c_vec) = *elm;
2341 let a = BigInt::from_slice(Plus, a_vec);
2342 let b = BigInt::from_slice(Plus, b_vec);
2343 let c = BigInt::from_slice(Plus, c_vec);
2345 assert!(a + b == c);
2346 assert!(b + a == c);
2347 assert!(c + (-a) == b);
2348 assert!(c + (-b) == a);
2349 assert!(a + (-c) == (-b));
2350 assert!(b + (-c) == (-a));
2351 assert!((-a) + (-b) == (-c))
2352 assert!(a + (-a) == Zero::zero());
2358 for elm in sum_triples.iter() {
2359 let (a_vec, b_vec, c_vec) = *elm;
2360 let a = BigInt::from_slice(Plus, a_vec);
2361 let b = BigInt::from_slice(Plus, b_vec);
2362 let c = BigInt::from_slice(Plus, c_vec);
2364 assert!(c - a == b);
2365 assert!(c - b == a);
2366 assert!((-b) - a == (-c))
2367 assert!((-a) - b == (-c))
2368 assert!(b - (-a) == c);
2369 assert!(a - (-b) == c);
2370 assert!((-c) - (-a) == (-b));
2371 assert!(a - a == Zero::zero());
2375 static mul_triples: &'static [(&'static [BigDigit],
2376 &'static [BigDigit],
2377 &'static [BigDigit])] = &[
2381 (&[ 1], &[ 1], &[1]),
2382 (&[ 2], &[ 3], &[ 6]),
2383 (&[ 1], &[ 1, 1, 1], &[1, 1, 1]),
2384 (&[ 1, 2, 3], &[ 3], &[ 3, 6, 9]),
2385 (&[ 1, 1, 1], &[-1], &[-1, -1, -1]),
2386 (&[ 1, 2, 3], &[-1], &[-1, -2, -2, 2]),
2387 (&[ 1, 2, 3, 4], &[-1], &[-1, -2, -2, -2, 3]),
2388 (&[-1], &[-1], &[ 1, -2]),
2389 (&[-1, -1], &[-1], &[ 1, -1, -2]),
2390 (&[-1, -1, -1], &[-1], &[ 1, -1, -1, -2]),
2391 (&[-1, -1, -1, -1], &[-1], &[ 1, -1, -1, -1, -2]),
2392 (&[-1/2 + 1], &[ 2], &[ 0, 1]),
2393 (&[0, -1/2 + 1], &[ 2], &[ 0, 0, 1]),
2394 (&[ 1, 2], &[ 1, 2, 3], &[1, 4, 7, 6]),
2395 (&[-1, -1], &[-1, -1, -1], &[1, 0, -1, -2, -1]),
2396 (&[-1, -1, -1], &[-1, -1, -1, -1], &[1, 0, 0, -1, -2, -1, -1]),
2397 (&[ 0, 0, 1], &[ 1, 2, 3], &[0, 0, 1, 2, 3]),
2398 (&[ 0, 0, 1], &[ 0, 0, 0, 1], &[0, 0, 0, 0, 0, 1])
2401 static div_rem_quadruples: &'static [(&'static [BigDigit],
2402 &'static [BigDigit],
2403 &'static [BigDigit],
2404 &'static [BigDigit])]
2406 (&[ 1], &[ 2], &[], &[1]),
2407 (&[ 1, 1], &[ 2], &[-1/2+1], &[1]),
2408 (&[ 1, 1, 1], &[ 2], &[-1/2+1, -1/2+1], &[1]),
2409 (&[ 0, 1], &[-1], &[1], &[1]),
2410 (&[-1, -1], &[-2], &[2, 1], &[3])
2415 for elm in mul_triples.iter() {
2416 let (a_vec, b_vec, c_vec) = *elm;
2417 let a = BigInt::from_slice(Plus, a_vec);
2418 let b = BigInt::from_slice(Plus, b_vec);
2419 let c = BigInt::from_slice(Plus, c_vec);
2421 assert!(a * b == c);
2422 assert!(b * a == c);
2424 assert!((-a) * b == -c);
2425 assert!((-b) * a == -c);
2428 for elm in div_rem_quadruples.iter() {
2429 let (a_vec, b_vec, c_vec, d_vec) = *elm;
2430 let a = BigInt::from_slice(Plus, a_vec);
2431 let b = BigInt::from_slice(Plus, b_vec);
2432 let c = BigInt::from_slice(Plus, c_vec);
2433 let d = BigInt::from_slice(Plus, d_vec);
2435 assert!(a == b * c + d);
2436 assert!(a == c * b + d);
2441 fn test_div_mod_floor() {
2442 fn check_sub(a: &BigInt, b: &BigInt, ans_d: &BigInt, ans_m: &BigInt) {
2443 let (d, m) = a.div_mod_floor(b);
2445 assert_eq!(m.sign, b.sign);
2447 assert!(m.abs() <= b.abs());
2448 assert!(*a == b * d + m);
2449 assert!(d == *ans_d);
2450 assert!(m == *ans_m);
2453 fn check(a: &BigInt, b: &BigInt, d: &BigInt, m: &BigInt) {
2455 check_sub(a, b, d, m);
2456 check_sub(a, &b.neg(), &d.neg(), m);
2457 check_sub(&a.neg(), b, &d.neg(), m);
2458 check_sub(&a.neg(), &b.neg(), d, m);
2460 check_sub(a, b, d, m);
2461 check_sub(a, &b.neg(), &(d.neg() - One::one()), &(m - *b));
2462 check_sub(&a.neg(), b, &(d.neg() - One::one()), &(b - *m));
2463 check_sub(&a.neg(), &b.neg(), d, &m.neg());
2467 for elm in mul_triples.iter() {
2468 let (a_vec, b_vec, c_vec) = *elm;
2469 let a = BigInt::from_slice(Plus, a_vec);
2470 let b = BigInt::from_slice(Plus, b_vec);
2471 let c = BigInt::from_slice(Plus, c_vec);
2473 if !a.is_zero() { check(&c, &a, &b, &Zero::zero()); }
2474 if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); }
2477 for elm in div_rem_quadruples.iter() {
2478 let (a_vec, b_vec, c_vec, d_vec) = *elm;
2479 let a = BigInt::from_slice(Plus, a_vec);
2480 let b = BigInt::from_slice(Plus, b_vec);
2481 let c = BigInt::from_slice(Plus, c_vec);
2482 let d = BigInt::from_slice(Plus, d_vec);
2485 check(&a, &b, &c, &d);
2493 fn check_sub(a: &BigInt, b: &BigInt, ans_q: &BigInt, ans_r: &BigInt) {
2494 let (q, r) = a.div_rem(b);
2496 assert_eq!(r.sign, a.sign);
2498 assert!(r.abs() <= b.abs());
2499 assert!(*a == b * q + r);
2500 assert!(q == *ans_q);
2501 assert!(r == *ans_r);
2504 fn check(a: &BigInt, b: &BigInt, q: &BigInt, r: &BigInt) {
2505 check_sub(a, b, q, r);
2506 check_sub(a, &b.neg(), &q.neg(), r);
2507 check_sub(&a.neg(), b, &q.neg(), &r.neg());
2508 check_sub(&a.neg(), &b.neg(), q, &r.neg());
2510 for elm in mul_triples.iter() {
2511 let (a_vec, b_vec, c_vec) = *elm;
2512 let a = BigInt::from_slice(Plus, a_vec);
2513 let b = BigInt::from_slice(Plus, b_vec);
2514 let c = BigInt::from_slice(Plus, c_vec);
2516 if !a.is_zero() { check(&c, &a, &b, &Zero::zero()); }
2517 if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); }
2520 for elm in div_rem_quadruples.iter() {
2521 let (a_vec, b_vec, c_vec, d_vec) = *elm;
2522 let a = BigInt::from_slice(Plus, a_vec);
2523 let b = BigInt::from_slice(Plus, b_vec);
2524 let c = BigInt::from_slice(Plus, c_vec);
2525 let d = BigInt::from_slice(Plus, d_vec);
2528 check(&a, &b, &c, &d);
2534 fn test_checked_add() {
2535 for elm in sum_triples.iter() {
2536 let (aVec, bVec, cVec) = *elm;
2537 let a = BigInt::from_slice(Plus, aVec);
2538 let b = BigInt::from_slice(Plus, bVec);
2539 let c = BigInt::from_slice(Plus, cVec);
2541 assert!(a.checked_add(&b).unwrap() == c);
2542 assert!(b.checked_add(&a).unwrap() == c);
2543 assert!(c.checked_add(&(-a)).unwrap() == b);
2544 assert!(c.checked_add(&(-b)).unwrap() == a);
2545 assert!(a.checked_add(&(-c)).unwrap() == (-b));
2546 assert!(b.checked_add(&(-c)).unwrap() == (-a));
2547 assert!((-a).checked_add(&(-b)).unwrap() == (-c))
2548 assert!(a.checked_add(&(-a)).unwrap() == Zero::zero());
2553 fn test_checked_sub() {
2554 for elm in sum_triples.iter() {
2555 let (aVec, bVec, cVec) = *elm;
2556 let a = BigInt::from_slice(Plus, aVec);
2557 let b = BigInt::from_slice(Plus, bVec);
2558 let c = BigInt::from_slice(Plus, cVec);
2560 assert!(c.checked_sub(&a).unwrap() == b);
2561 assert!(c.checked_sub(&b).unwrap() == a);
2562 assert!((-b).checked_sub(&a).unwrap() == (-c))
2563 assert!((-a).checked_sub(&b).unwrap() == (-c))
2564 assert!(b.checked_sub(&(-a)).unwrap() == c);
2565 assert!(a.checked_sub(&(-b)).unwrap() == c);
2566 assert!((-c).checked_sub(&(-a)).unwrap() == (-b));
2567 assert!(a.checked_sub(&a).unwrap() == Zero::zero());
2572 fn test_checked_mul() {
2573 for elm in mul_triples.iter() {
2574 let (aVec, bVec, cVec) = *elm;
2575 let a = BigInt::from_slice(Plus, aVec);
2576 let b = BigInt::from_slice(Plus, bVec);
2577 let c = BigInt::from_slice(Plus, cVec);
2579 assert!(a.checked_mul(&b).unwrap() == c);
2580 assert!(b.checked_mul(&a).unwrap() == c);
2582 assert!((-a).checked_mul(&b).unwrap() == -c);
2583 assert!((-b).checked_mul(&a).unwrap() == -c);
2586 for elm in div_rem_quadruples.iter() {
2587 let (aVec, bVec, cVec, dVec) = *elm;
2588 let a = BigInt::from_slice(Plus, aVec);
2589 let b = BigInt::from_slice(Plus, bVec);
2590 let c = BigInt::from_slice(Plus, cVec);
2591 let d = BigInt::from_slice(Plus, dVec);
2593 assert!(a == b.checked_mul(&c).unwrap() + d);
2594 assert!(a == c.checked_mul(&b).unwrap() + d);
2598 fn test_checked_div() {
2599 for elm in mul_triples.iter() {
2600 let (aVec, bVec, cVec) = *elm;
2601 let a = BigInt::from_slice(Plus, aVec);
2602 let b = BigInt::from_slice(Plus, bVec);
2603 let c = BigInt::from_slice(Plus, cVec);
2606 assert!(c.checked_div(&a).unwrap() == b);
2607 assert!((-c).checked_div(&(-a)).unwrap() == b);
2608 assert!((-c).checked_div(&a).unwrap() == -b);
2611 assert!(c.checked_div(&b).unwrap() == a);
2612 assert!((-c).checked_div(&(-b)).unwrap() == a);
2613 assert!((-c).checked_div(&b).unwrap() == -a);
2616 assert!(c.checked_div(&Zero::zero()).is_none());
2617 assert!((-c).checked_div(&Zero::zero()).is_none());
2623 fn check(a: int, b: int, c: int) {
2624 let big_a: BigInt = FromPrimitive::from_int(a).unwrap();
2625 let big_b: BigInt = FromPrimitive::from_int(b).unwrap();
2626 let big_c: BigInt = FromPrimitive::from_int(c).unwrap();
2628 assert_eq!(big_a.gcd(&big_b), big_c);
2643 fn check(a: int, b: int, c: int) {
2644 let big_a: BigInt = FromPrimitive::from_int(a).unwrap();
2645 let big_b: BigInt = FromPrimitive::from_int(b).unwrap();
2646 let big_c: BigInt = FromPrimitive::from_int(c).unwrap();
2648 assert_eq!(big_a.lcm(&big_b), big_c);
2663 let zero: BigInt = Zero::zero();
2664 let one: BigInt = One::one();
2665 assert_eq!((-one).abs_sub(&one), zero);
2666 let one: BigInt = One::one();
2667 let zero: BigInt = Zero::zero();
2668 assert_eq!(one.abs_sub(&one), zero);
2669 let one: BigInt = One::one();
2670 let zero: BigInt = Zero::zero();
2671 assert_eq!(one.abs_sub(&zero), one);
2672 let one: BigInt = One::one();
2673 let two: BigInt = FromPrimitive::from_int(2).unwrap();
2674 assert_eq!(one.abs_sub(&-one), two);
2678 fn test_to_str_radix() {
2679 fn check(n: int, ans: &str) {
2680 let n: BigInt = FromPrimitive::from_int(n).unwrap();
2681 assert!(ans == n.to_str_radix(10));
2692 fn test_from_str_radix() {
2693 fn check(s: &str, ans: Option<int>) {
2694 let ans = ans.map(|n| {
2695 let x: BigInt = FromPrimitive::from_int(n).unwrap();
2698 assert_eq!(FromStrRadix::from_str_radix(s, 10), ans);
2700 check("10", Some(10));
2701 check("1", Some(1));
2702 check("0", Some(0));
2703 check("-1", Some(-1));
2704 check("-10", Some(-10));
2708 // issue 10522, this hit an edge case that caused it to
2709 // attempt to allocate a vector of size (-1u) == huge.
2710 let x: BigInt = from_str("1" + "0".repeat(36)).unwrap();
2711 let _y = x.to_str();
2716 assert!(-BigInt::new(Plus, vec!(1, 1, 1)) ==
2717 BigInt::new(Minus, vec!(1, 1, 1)));
2718 assert!(-BigInt::new(Minus, vec!(1, 1, 1)) ==
2719 BigInt::new(Plus, vec!(1, 1, 1)));
2720 let zero: BigInt = Zero::zero();
2721 assert_eq!(-zero, zero);
2726 let mut rng = task_rng();
2727 let _n: BigInt = rng.gen_bigint(137);
2728 assert!(rng.gen_bigint(0).is_zero());
2732 fn test_rand_range() {
2733 let mut rng = task_rng();
2735 for _ in range(0, 10) {
2736 assert_eq!(rng.gen_bigint_range(&FromPrimitive::from_uint(236).unwrap(),
2737 &FromPrimitive::from_uint(237).unwrap()),
2738 FromPrimitive::from_uint(236).unwrap());
2741 fn check(l: BigInt, u: BigInt) {
2742 let mut rng = task_rng();
2743 for _ in range(0, 1000) {
2744 let n: BigInt = rng.gen_bigint_range(&l, &u);
2749 let l: BigInt = FromPrimitive::from_uint(403469000 + 2352).unwrap();
2750 let u: BigInt = FromPrimitive::from_uint(403469000 + 3513).unwrap();
2751 check( l.clone(), u.clone());
2752 check(-l.clone(), u.clone());
2753 check(-u.clone(), -l.clone());
2758 fn test_zero_rand_range() {
2759 task_rng().gen_bigint_range(&FromPrimitive::from_int(54).unwrap(),
2760 &FromPrimitive::from_int(54).unwrap());
2765 fn test_negative_rand_range() {
2766 let mut rng = task_rng();
2767 let l = FromPrimitive::from_uint(2352).unwrap();
2768 let u = FromPrimitive::from_uint(3513).unwrap();
2769 // Switching u and l should fail:
2770 let _n: BigInt = rng.gen_bigint_range(&u, &l);
2777 use self::test::BenchHarness;
2780 use std::mem::replace;
2781 use std::num::{FromPrimitive, Zero, One};
2783 fn factorial(n: uint) -> BigUint {
2784 let mut f: BigUint = One::one();
2785 for i in iter::range_inclusive(1, n) {
2786 f = f * FromPrimitive::from_uint(i).unwrap();
2791 fn fib(n: uint) -> BigUint {
2792 let mut f0: BigUint = Zero::zero();
2793 let mut f1: BigUint = One::one();
2794 for _ in range(0, n) {
2796 f0 = replace(&mut f1, f2);
2802 fn factorial_100(bh: &mut BenchHarness) {
2809 fn fib_100(bh: &mut BenchHarness) {
2816 fn to_str(bh: &mut BenchHarness) {
2817 let fac = factorial(100);
2828 fn shr(bh: &mut BenchHarness) {
2829 let n = { let one : BigUint = One::one(); one << 1000 };
2831 let mut m = n.clone();
2832 for _ in range(0, 10) {