63: chore: run rustfmt on all code r=cuviper a=dignifiedquire



Co-authored-by: dignifiedquire <dignifiedquire@gmail.com>
This commit is contained in:
bors[bot] 2018-08-06 22:33:55 +00:00
commit 1a316783b5
22 changed files with 1555 additions and 1280 deletions

View File

@ -1,17 +1,17 @@
#![feature(test)]
#![cfg(feature = "rand")]
extern crate test;
extern crate num_bigint;
extern crate num_traits;
extern crate num_integer;
extern crate num_traits;
extern crate rand;
extern crate test;
use num_bigint::{BigInt, BigUint, RandBigInt};
use num_traits::{FromPrimitive, Num, One, Pow, Zero};
use rand::{SeedableRng, StdRng};
use std::mem::replace;
use test::Bencher;
use num_bigint::{BigInt, BigUint, RandBigInt};
use num_traits::{Zero, One, FromPrimitive, Num, Pow};
use rand::{SeedableRng, StdRng};
fn get_rng() -> StdRng {
let mut seed = [0; 32];
@ -39,7 +39,7 @@ fn divide_bench(b: &mut Bencher, xbits: usize, ybits: usize) {
fn factorial(n: usize) -> BigUint {
let mut f: BigUint = One::one();
for i in 1..(n+1) {
for i in 1..(n + 1) {
let bu: BigUint = FromPrimitive::from_usize(i).unwrap();
f = f * bu;
}
@ -307,21 +307,21 @@ fn pow_bench(b: &mut Bencher) {
});
}
/// This modulus is the prime from the 2048-bit MODP DH group:
/// https://tools.ietf.org/html/rfc3526#section-3
const RFC3526_2048BIT_MODP_GROUP: &'static str = "\
FFFFFFFF_FFFFFFFF_C90FDAA2_2168C234_C4C6628B_80DC1CD1\
29024E08_8A67CC74_020BBEA6_3B139B22_514A0879_8E3404DD\
EF9519B3_CD3A431B_302B0A6D_F25F1437_4FE1356D_6D51C245\
E485B576_625E7EC6_F44C42E9_A637ED6B_0BFF5CB6_F406B7ED\
EE386BFB_5A899FA5_AE9F2411_7C4B1FE6_49286651_ECE45B3D\
C2007CB8_A163BF05_98DA4836_1C55D39A_69163FA8_FD24CF5F\
83655D23_DCA3AD96_1C62F356_208552BB_9ED52907_7096966D\
670C354E_4ABC9804_F1746C08_CA18217C_32905E46_2E36CE3B\
E39E772C_180E8603_9B2783A2_EC07A28F_B5C55DF0_6F4C52C9\
DE2BCBF6_95581718_3995497C_EA956AE5_15D22618_98FA0510\
15728E5A_8AACAA68_FFFFFFFF_FFFFFFFF";
const RFC3526_2048BIT_MODP_GROUP: &'static str =
"\
FFFFFFFF_FFFFFFFF_C90FDAA2_2168C234_C4C6628B_80DC1CD1\
29024E08_8A67CC74_020BBEA6_3B139B22_514A0879_8E3404DD\
EF9519B3_CD3A431B_302B0A6D_F25F1437_4FE1356D_6D51C245\
E485B576_625E7EC6_F44C42E9_A637ED6B_0BFF5CB6_F406B7ED\
EE386BFB_5A899FA5_AE9F2411_7C4B1FE6_49286651_ECE45B3D\
C2007CB8_A163BF05_98DA4836_1C55D39A_69163FA8_FD24CF5F\
83655D23_DCA3AD96_1C62F356_208552BB_9ED52907_7096966D\
670C354E_4ABC9804_F1746C08_CA18217C_32905E46_2E36CE3B\
E39E772C_180E8603_9B2783A2_EC07A28F_B5C55DF0_6F4C52C9\
DE2BCBF6_95581718_3995497C_EA956AE5_15D22618_98FA0510\
15728E5A_8AACAA68_FFFFFFFF_FFFFFFFF";
#[bench]
fn modpow(b: &mut Bencher) {

View File

@ -11,7 +11,11 @@ use test::Bencher;
#[bench]
fn factorial_mul_biguint(b: &mut Bencher) {
b.iter(|| (1u32..1000).map(BigUint::from).fold(BigUint::one(), Mul::mul));
b.iter(|| {
(1u32..1000)
.map(BigUint::from)
.fold(BigUint::one(), Mul::mul)
});
}
#[bench]
@ -25,7 +29,12 @@ fn factorial_mul_u32(b: &mut Bencher) {
#[bench]
fn factorial_div_biguint(b: &mut Bencher) {
let n: BigUint = (1u32..1000).fold(BigUint::one(), Mul::mul);
b.iter(|| (1u32..1000).rev().map(BigUint::from).fold(n.clone(), Div::div));
b.iter(|| {
(1u32..1000)
.rev()
.map(BigUint::from)
.fold(n.clone(), Div::div)
});
}
#[bench]

View File

@ -1,17 +1,17 @@
#![feature(test)]
#![cfg(feature = "rand")]
extern crate test;
extern crate num_bigint;
extern crate num_integer;
extern crate num_traits;
extern crate rand;
extern crate test;
use test::Bencher;
use num_bigint::{BigUint, RandBigInt};
use num_integer::Integer;
use num_traits::Zero;
use rand::{SeedableRng, StdRng};
use test::Bencher;
fn get_rng() -> StdRng {
let mut seed = [0; 32];
@ -31,7 +31,6 @@ fn bench(b: &mut Bencher, bits: usize, gcd: fn(&BigUint, &BigUint) -> BigUint) {
b.iter(|| gcd(&x, &y));
}
fn euclid(x: &BigUint, y: &BigUint) -> BigUint {
// Use Euclid's algorithm
let mut m = x.clone();
@ -64,7 +63,6 @@ fn gcd_euclid_4096(b: &mut Bencher) {
bench(b, 4096, euclid);
}
// Integer for BigUint now uses Stein for gcd
#[bench]

View File

@ -42,12 +42,12 @@ extern crate num_bigint;
extern crate num_integer;
extern crate num_traits;
use std::str::FromStr;
use std::io;
use std::str::FromStr;
use num_bigint::BigInt;
use num_integer::Integer;
use num_traits::{FromPrimitive, ToPrimitive, One, Zero};
use num_traits::{FromPrimitive, One, ToPrimitive, Zero};
struct Context {
numer: BigInt,
@ -69,11 +69,13 @@ impl Context {
}
fn extract_digit(&self) -> i32 {
if self.numer > self.accum {return -1;}
let (q, r) =
(&self.numer * Context::from_i32(3) + &self.accum)
.div_rem(&self.denom);
if r + &self.numer >= self.denom {return -1;}
if self.numer > self.accum {
return -1;
}
let (q, r) = (&self.numer * Context::from_i32(3) + &self.accum).div_rem(&self.denom);
if r + &self.numer >= self.denom {
return -1;
}
q.to_i32().unwrap()
}
@ -96,24 +98,30 @@ fn pidigits(n: isize, out: &mut io::Write) -> io::Result<()> {
let mut k = 0;
let mut context = Context::new();
for i in 1..(n+1) {
for i in 1..(n + 1) {
let mut d;
loop {
k += 1;
context.next_term(k);
d = context.extract_digit();
if d != -1 {break;}
if d != -1 {
break;
}
}
try!(write!(out, "{}", d));
if i % 10 == 0 { try!(write!(out, "\t:{}\n", i)); }
if i % 10 == 0 {
try!(write!(out, "\t:{}\n", i));
}
context.eliminate_digit(d);
}
let m = n % 10;
if m != 0 {
for _ in m..10 { try!(write!(out, " ")); }
for _ in m..10 {
try!(write!(out, " "));
}
try!(write!(out, "\t:{}\n", n));
}
Ok(())
@ -126,7 +134,7 @@ fn main() {
let n = if args.len() < 2 {
DEFAULT_DIGITS
} else if args[1] == "--bench" {
return pidigits(DEFAULT_DIGITS, &mut std::io::sink()).unwrap()
return pidigits(DEFAULT_DIGITS, &mut std::io::sink()).unwrap();
} else {
FromStr::from_str(&args[1]).unwrap()
};

View File

@ -1,10 +1,10 @@
use std::borrow::Cow;
use std::cmp;
use std::cmp::Ordering::{self, Less, Greater, Equal};
use std::cmp::Ordering::{self, Equal, Greater, Less};
use std::iter::repeat;
use std::mem;
use traits;
use traits::{Zero, One};
use traits::{One, Zero};
use biguint::BigUint;
@ -95,7 +95,9 @@ pub fn __add2(a: &mut [BigDigit], b: &[BigDigit]) -> BigDigit {
if carry != 0 {
for a in a_hi {
*a = adc(*a, 0, &mut carry);
if carry == 0 { break }
if carry == 0 {
break;
}
}
}
@ -127,13 +129,17 @@ pub fn sub2(a: &mut [BigDigit], b: &[BigDigit]) {
if borrow != 0 {
for a in a_hi {
*a = sbb(*a, 0, &mut borrow);
if borrow == 0 { break }
if borrow == 0 {
break;
}
}
}
// note: we're _required_ to fail on underflow
assert!(borrow == 0 && b_hi.iter().all(|x| *x == 0),
"Cannot subtract b from a because b is larger than a.");
assert!(
borrow == 0 && b_hi.iter().all(|x| *x == 0),
"Cannot subtract b from a because b is larger than a."
);
}
// Only for the Sub impl. `a` and `b` must have same length.
@ -162,8 +168,10 @@ pub fn sub2rev(a: &[BigDigit], b: &mut [BigDigit]) {
assert!(a_hi.is_empty());
// note: we're _required_ to fail on underflow
assert!(borrow == 0 && b_hi.iter().all(|x| *x == 0),
"Cannot subtract b from a because b is larger than a.");
assert!(
borrow == 0 && b_hi.iter().all(|x| *x == 0),
"Cannot subtract b from a because b is larger than a."
);
}
pub fn sub_sign(a: &[BigDigit], b: &[BigDigit]) -> (Sign, BigUint) {
@ -210,11 +218,7 @@ pub fn mac_digit(acc: &mut [BigDigit], b: &[BigDigit], c: BigDigit) {
/// Three argument multiply accumulate:
/// acc += b * c
fn mac3(acc: &mut [BigDigit], b: &[BigDigit], c: &[BigDigit]) {
let (x, y) = if b.len() < c.len() {
(b, c)
} else {
(c, b)
};
let (x, y) = if b.len() < c.len() { (b, c) } else { (c, b) };
// We use three algorithms for different input sizes.
//
@ -317,8 +321,8 @@ fn mac3(acc: &mut [BigDigit], b: &[BigDigit], c: &[BigDigit]) {
// Not required, but the adds go faster if we drop any unneeded 0s from the end:
p.normalize();
add2(&mut acc[b..], &p.data[..]);
add2(&mut acc[b * 2..], &p.data[..]);
add2(&mut acc[b..], &p.data[..]);
add2(&mut acc[b * 2..], &p.data[..]);
// Zero out p before the next multiply:
p.data.truncate(0);
@ -328,8 +332,8 @@ fn mac3(acc: &mut [BigDigit], b: &[BigDigit], c: &[BigDigit]) {
mac3(&mut p.data[..], x0, y0);
p.normalize();
add2(&mut acc[..], &p.data[..]);
add2(&mut acc[b..], &p.data[..]);
add2(&mut acc[..], &p.data[..]);
add2(&mut acc[b..], &p.data[..]);
// p1 = (x1 - x0) * (y1 - y0)
// We do this one last, since it may be negative and acc can't ever be negative:
@ -337,7 +341,7 @@ fn mac3(acc: &mut [BigDigit], b: &[BigDigit], c: &[BigDigit]) {
let (j1_sign, j1) = sub_sign(y1, y0);
match j0_sign * j1_sign {
Plus => {
Plus => {
p.data.truncate(0);
p.data.extend(repeat(0).take(len));
@ -345,13 +349,12 @@ fn mac3(acc: &mut [BigDigit], b: &[BigDigit], c: &[BigDigit]) {
p.normalize();
sub2(&mut acc[b..], &p.data[..]);
},
Minus => {
}
Minus => {
mac3(&mut acc[b..], &j0.data[..], &j1.data[..]);
},
NoSign => (),
}
NoSign => (),
}
} else {
// Toom-3 multiplication:
//
@ -361,7 +364,7 @@ fn mac3(acc: &mut [BigDigit], b: &[BigDigit], c: &[BigDigit]) {
// The general idea is to treat the large integers digits as
// polynomials of a certain degree and determine the coefficients/digits
// of the product of the two via interpolation of the polynomial product.
let i = y.len()/3 + 1;
let i = y.len() / 3 + 1;
let x0_len = cmp::min(x.len(), i);
let x1_len = cmp::min(x.len() - x0_len, i);
@ -432,7 +435,7 @@ fn mac3(acc: &mut [BigDigit], b: &[BigDigit], c: &[BigDigit]) {
let r2 = &p2 * &q2;
// w(-2)
let r3 = ((p2 + x2)*2 - x0) * ((q2 + y2)*2 - y0);
let r3 = ((p2 + x2) * 2 - x0) * ((q2 + y2) * 2 - y0);
// Evaluating these points gives us the following system of linear equations.
//
@ -456,14 +459,18 @@ fn mac3(acc: &mut [BigDigit], b: &[BigDigit], c: &[BigDigit]) {
let mut comp3: BigInt = (r3 - &r1) / 3;
let mut comp1: BigInt = (r1 - &r2) / 2;
let mut comp2: BigInt = r2 - &r0;
comp3 = (&comp2 - comp3)/2 + &r4*2;
comp3 = (&comp2 - comp3) / 2 + &r4 * 2;
comp2 = comp2 + &comp1 - &r4;
comp1 = comp1 - &comp3;
// Recomposition. The coefficients of the polynomial are now known.
//
// Evaluate at w(t) where t is our given base to get the result.
let result = r0 + (comp1 << 32*i) + (comp2 << 2*32*i) + (comp3 << 3*32*i) + (r4 << 4*32*i);
let result = r0
+ (comp1 << 32 * i)
+ (comp2 << 2 * 32 * i)
+ (comp3 << 3 * 32 * i)
+ (r4 << 4 * 32 * i);
let result_pos = result.to_biguint().unwrap();
add2(&mut acc[..], &result_pos.data);
}
@ -533,13 +540,17 @@ pub fn div_rem(u: &BigUint, d: &BigUint) -> (BigUint, BigUint) {
let bn = *b.data.last().unwrap();
let q_len = a.data.len() - b.data.len() + 1;
let mut q = BigUint { data: vec![0; q_len] };
let mut q = BigUint {
data: vec![0; q_len],
};
// We reuse the same temporary to avoid hitting the allocator in our inner loop - this is
// sized to hold a0 (in the common case; if a particular digit of the quotient is zero a0
// can be bigger).
//
let mut tmp = BigUint { data: Vec::with_capacity(2) };
let mut tmp = BigUint {
data: Vec::with_capacity(2),
};
for j in (0..q_len).rev() {
/*
@ -678,9 +689,9 @@ pub fn cmp_slice(a: &[BigDigit], b: &[BigDigit]) -> Ordering {
#[cfg(test)]
mod algorithm_tests {
use big_digit::BigDigit;
use {BigUint, BigInt};
use Sign::Plus;
use traits::Num;
use Sign::Plus;
use {BigInt, BigUint};
#[test]
fn test_sub_sign() {

View File

@ -1,24 +1,27 @@
use std::default::Default;
use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Not, Rem, Shl, Shr, Sub,
AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, DivAssign,
MulAssign, RemAssign, ShlAssign, ShrAssign, SubAssign};
use std::str::{self, FromStr};
use std::fmt;
use std::mem;
use std::cmp::Ordering::{self, Less, Greater, Equal};
use std::{i64, u64};
#[cfg(has_i128)]
use std::{i128, u128};
#[allow(deprecated, unused_imports)]
use std::ascii::AsciiExt;
use std::cmp::Ordering::{self, Equal, Greater, Less};
use std::default::Default;
use std::fmt;
use std::iter::{Product, Sum};
use std::mem;
use std::ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
};
use std::str::{self, FromStr};
#[cfg(has_i128)]
use std::{i128, u128};
use std::{i64, u64};
#[cfg(feature = "serde")]
use serde;
use integer::{Integer, Roots};
use traits::{ToPrimitive, FromPrimitive, Num, CheckedAdd, CheckedSub,
CheckedMul, CheckedDiv, Signed, Zero, One, Pow};
use traits::{
CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, FromPrimitive, Num, One, Pow, Signed,
ToPrimitive, Zero,
};
use self::Sign::{Minus, NoSign, Plus};
@ -28,8 +31,8 @@ use biguint;
use biguint::to_str_radix_reversed;
use biguint::{BigUint, IntDigits};
use UsizePromotion;
use IsizePromotion;
use UsizePromotion;
/// A Sign is a `BigInt`'s composing element.
#[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone, Debug, Hash)]
@ -69,7 +72,8 @@ impl Mul<Sign> for Sign {
#[cfg(feature = "serde")]
impl serde::Serialize for Sign {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer
where
S: serde::Serializer,
{
// Note: do not change the serialization format, or it may break
// forward and backward compatibility of serialized data!
@ -84,7 +88,8 @@ impl serde::Serialize for Sign {
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for Sign {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::Deserializer<'de>
where
D: serde::Deserializer<'de>,
{
use serde::de::Error;
use serde::de::Unexpected;
@ -235,11 +240,7 @@ impl Not for BigInt {
}
Minus => {
self.data -= 1u32;
self.sign = if self.data.is_zero() {
NoSign
} else {
Plus
};
self.sign = if self.data.is_zero() { NoSign } else { Plus };
}
}
self
@ -302,7 +303,7 @@ fn bitand_neg_neg(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
}
debug_assert!(a.len() > b.len() || carry_a == 0);
debug_assert!(b.len() > a.len() || carry_b == 0);
if a.len() > b.len() {
if a.len() > b.len() {
for ai in a[b.len()..].iter_mut() {
let twos_a = negate_carry(*ai, &mut carry_a);
*ai = negate_carry(twos_a, &mut carry_and);
@ -709,10 +710,9 @@ impl ShlAssign<usize> for BigInt {
// Negative values need a rounding adjustment if there are any ones in the
// bits that are getting shifted out.
fn shr_round_down(i: &BigInt, rhs: usize) -> bool {
i.is_negative() &&
biguint::trailing_zeros(&i.data)
.map(|n| n < rhs)
.unwrap_or(false)
i.is_negative() && biguint::trailing_zeros(&i.data)
.map(|n| n < rhs)
.unwrap_or(false)
}
impl Shr<usize> for BigInt {
@ -811,7 +811,6 @@ impl Signed for BigInt {
}
}
/// Help function for pow
///
/// Computes the effect of the exponent on the sign.
@ -847,7 +846,7 @@ macro_rules! pow_impl {
BigInt::from_biguint(powsign(self.sign, rhs), (&self.data).pow(rhs))
}
}
}
};
}
pow_impl!(u8);
@ -858,7 +857,6 @@ pow_impl!(usize);
#[cfg(has_i128)]
pow_impl!(u128);
// A convenience method for getting the absolute value of an i32 in a u32.
#[inline]
fn i32_abs_as_u32(a: i32) -> u32 {
@ -888,15 +886,13 @@ macro_rules! bigint_add {
(_, NoSign) => $a_owned,
(NoSign, _) => $b_owned,
// same sign => keep the sign with the sum of magnitudes
(Plus, Plus) | (Minus, Minus) =>
BigInt::from_biguint($a.sign, $a_data + $b_data),
(Plus, Plus) | (Minus, Minus) => BigInt::from_biguint($a.sign, $a_data + $b_data),
// opposite signs => keep the sign of the larger with the difference of magnitudes
(Plus, Minus) | (Minus, Plus) =>
match $a.data.cmp(&$b.data) {
Less => BigInt::from_biguint($b.sign, $b_data - $a_data),
Greater => BigInt::from_biguint($a.sign, $a_data - $b_data),
Equal => Zero::zero(),
},
(Plus, Minus) | (Minus, Plus) => match $a.data.cmp(&$b.data) {
Less => BigInt::from_biguint($b.sign, $b_data - $a_data),
Greater => BigInt::from_biguint($a.sign, $a_data - $b_data),
Equal => Zero::zero(),
},
}
};
}
@ -906,12 +902,14 @@ impl<'a, 'b> Add<&'b BigInt> for &'a BigInt {
#[inline]
fn add(self, other: &BigInt) -> BigInt {
bigint_add!(self,
self.clone(),
&self.data,
other,
other.clone(),
&other.data)
bigint_add!(
self,
self.clone(),
&self.data,
other,
other.clone(),
&other.data
)
}
}
@ -964,12 +962,11 @@ impl Add<BigDigit> for BigInt {
match self.sign {
NoSign => From::from(other),
Plus => BigInt::from_biguint(Plus, self.data + other),
Minus =>
match self.data.cmp(&From::from(other)) {
Equal => Zero::zero(),
Less => BigInt::from_biguint(Plus, other - self.data),
Greater => BigInt::from_biguint(Minus, self.data - other),
}
Minus => match self.data.cmp(&From::from(other)) {
Equal => Zero::zero(),
Less => BigInt::from_biguint(Plus, other - self.data),
Greater => BigInt::from_biguint(Minus, self.data - other),
},
}
}
}
@ -989,12 +986,11 @@ impl Add<DoubleBigDigit> for BigInt {
match self.sign {
NoSign => From::from(other),
Plus => BigInt::from_biguint(Plus, self.data + other),
Minus =>
match self.data.cmp(&From::from(other)) {
Equal => Zero::zero(),
Less => BigInt::from_biguint(Plus, other - self.data),
Greater => BigInt::from_biguint(Minus, self.data - other),
}
Minus => match self.data.cmp(&From::from(other)) {
Equal => Zero::zero(),
Less => BigInt::from_biguint(Plus, other - self.data),
Greater => BigInt::from_biguint(Minus, self.data - other),
},
}
}
}
@ -1082,12 +1078,14 @@ impl<'a, 'b> Sub<&'b BigInt> for &'a BigInt {
#[inline]
fn sub(self, other: &BigInt) -> BigInt {
bigint_sub!(self,
self.clone(),
&self.data,
other,
other.clone(),
&other.data)
bigint_sub!(
self,
self.clone(),
&self.data,
other,
other.clone(),
&other.data
)
}
}
@ -1140,12 +1138,11 @@ impl Sub<BigDigit> for BigInt {
match self.sign {
NoSign => BigInt::from_biguint(Minus, From::from(other)),
Minus => BigInt::from_biguint(Minus, self.data + other),
Plus =>
match self.data.cmp(&From::from(other)) {
Equal => Zero::zero(),
Greater => BigInt::from_biguint(Plus, self.data - other),
Less => BigInt::from_biguint(Minus, other - self.data),
}
Plus => match self.data.cmp(&From::from(other)) {
Equal => Zero::zero(),
Greater => BigInt::from_biguint(Plus, self.data - other),
Less => BigInt::from_biguint(Minus, other - self.data),
},
}
}
}
@ -1174,12 +1171,11 @@ impl Sub<DoubleBigDigit> for BigInt {
match self.sign {
NoSign => BigInt::from_biguint(Minus, From::from(other)),
Minus => BigInt::from_biguint(Minus, self.data + other),
Plus =>
match self.data.cmp(&From::from(other)) {
Equal => Zero::zero(),
Greater => BigInt::from_biguint(Plus, self.data - other),
Less => BigInt::from_biguint(Minus, other - self.data),
}
Plus => match self.data.cmp(&From::from(other)) {
Equal => Zero::zero(),
Greater => BigInt::from_biguint(Plus, self.data - other),
Less => BigInt::from_biguint(Minus, other - self.data),
},
}
}
}
@ -1852,8 +1848,11 @@ impl Integer for BigInt {
impl Roots for BigInt {
fn nth_root(&self, n: u32) -> Self {
assert!(!(self.is_negative() && n.is_even()),
"root of degree {} is imaginary", n);
assert!(
!(self.is_negative() && n.is_even()),
"root of degree {} is imaginary",
n
);
BigInt::from_biguint(self.sign, self.data.nth_root(n))
}
@ -1875,18 +1874,16 @@ impl ToPrimitive for BigInt {
match self.sign {
Plus => self.data.to_i64(),
NoSign => Some(0),
Minus => {
self.data.to_u64().and_then(|n| {
let m: u64 = 1 << 63;
if n < m {
Some(-(n as i64))
} else if n == m {
Some(i64::MIN)
} else {
None
}
})
}
Minus => self.data.to_u64().and_then(|n| {
let m: u64 = 1 << 63;
if n < m {
Some(-(n as i64))
} else if n == m {
Some(i64::MIN)
} else {
None
}
}),
}
}
@ -1896,18 +1893,16 @@ impl ToPrimitive for BigInt {
match self.sign {
Plus => self.data.to_i128(),
NoSign => Some(0),
Minus => {
self.data.to_u128().and_then(|n| {
let m: u128 = 1 << 127;
if n < m {
Some(-(n as i128))
} else if n == m {
Some(i128::MIN)
} else {
None
}
})
}
Minus => self.data.to_u128().and_then(|n| {
let m: u128 = 1 << 127;
if n < m {
Some(-(n as i128))
} else if n == m {
Some(i128::MIN)
} else {
None
}
}),
}
}
@ -1932,24 +1927,16 @@ impl ToPrimitive for BigInt {
#[inline]
fn to_f32(&self) -> Option<f32> {
self.data.to_f32().map(|n| {
if self.sign == Minus {
-n
} else {
n
}
})
self.data
.to_f32()
.map(|n| if self.sign == Minus { -n } else { n })
}
#[inline]
fn to_f64(&self) -> Option<f64> {
self.data.to_f64().map(|n| {
if self.sign == Minus {
-n
} else {
n
}
})
self.data
.to_f64()
.map(|n| if self.sign == Minus { -n } else { n })
}
}
@ -2025,7 +2012,7 @@ macro_rules! impl_bigint_from_int {
BigInt::from(n as i64)
}
}
}
};
}
impl_bigint_from_int!(i8);
@ -2070,7 +2057,7 @@ macro_rules! impl_bigint_from_uint {
BigInt::from(n as u64)
}
}
}
};
}
impl_bigint_from_uint!(u8);
@ -2121,7 +2108,8 @@ impl IntDigits for BigInt {
#[cfg(feature = "serde")]
impl serde::Serialize for BigInt {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer
where
S: serde::Serializer,
{
// Note: do not change the serialization format, or it may break
// forward and backward compatibility of serialized data!
@ -2132,7 +2120,8 @@ impl serde::Serialize for BigInt {
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for BigInt {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::Deserializer<'de>
where
D: serde::Deserializer<'de>,
{
let (sign, data) = serde::Deserialize::deserialize(deserializer)?;
Ok(BigInt::from_biguint(sign, data))
@ -2170,9 +2159,9 @@ impl biguint::ToBigUint for BigInt {
#[inline]
fn to_biguint(&self) -> Option<BigUint> {
match self.sign() {
Plus => Some(self.data.clone()),
NoSign => Some(Zero::zero()),
Minus => None,
Plus => Some(self.data.clone()),
NoSign => Some(Zero::zero()),
Minus => None,
}
}
}
@ -2185,7 +2174,7 @@ macro_rules! impl_to_bigint {
$from_ty(*self)
}
}
}
};
}
impl_to_bigint!(isize, FromPrimitive::from_isize);
@ -2341,7 +2330,9 @@ impl BigInt {
/// ```
#[inline]
pub fn parse_bytes(buf: &[u8], radix: u32) -> Option<BigInt> {
str::from_utf8(buf).ok().and_then(|s| BigInt::from_str_radix(s, radix).ok())
str::from_utf8(buf)
.ok()
.and_then(|s| BigInt::from_str_radix(s, radix).ok())
}
/// Creates and initializes a `BigInt`. Each u8 of the input slice is
@ -2452,7 +2443,8 @@ impl BigInt {
pub fn to_signed_bytes_le(&self) -> Vec<u8> {
let mut bytes = self.data.to_bytes_le();
let last_byte = bytes.last().map(|v| *v).unwrap_or(0);
if last_byte > 0x7f && !(last_byte == 0x80 && bytes.iter().rev().skip(1).all(Zero::is_zero)) {
if last_byte > 0x7f && !(last_byte == 0x80 && bytes.iter().rev().skip(1).all(Zero::is_zero))
{
// msb used by magnitude, extend by 1 byte
bytes.push(0);
}
@ -2588,7 +2580,10 @@ impl BigInt {
///
/// Panics if the exponent is negative or the modulus is zero.
pub fn modpow(&self, exponent: &Self, modulus: &Self) -> Self {
assert!(!exponent.is_negative(), "negative exponentiation is not supported!");
assert!(
!exponent.is_negative(),
"negative exponentiation is not supported!"
);
assert!(!modulus.is_zero(), "divide by zero!");
let result = self.data.modpow(&exponent.data, &modulus.data);
@ -2646,7 +2641,8 @@ fn twos_complement_be(digits: &mut [u8]) {
/// starting from the least significant byte.
#[inline]
fn twos_complement<'a, I>(digits: I)
where I: IntoIterator<Item = &'a mut u8>
where
I: IntoIterator<Item = &'a mut u8>,
{
let mut carry = true;
for d in digits {
@ -2658,7 +2654,6 @@ fn twos_complement<'a, I>(digits: I)
}
}
#[test]
fn test_from_biguint() {
fn check(inp_s: Sign, inp_n: usize, ans_s: Sign, ans_n: usize) {

View File

@ -1,7 +1,7 @@
//! Randomization of big integers
use rand::prelude::*;
use rand::distributions::uniform::{SampleUniform, UniformSampler};
use rand::prelude::*;
use rand::AsByteSliceMut;
use BigInt;
@ -9,10 +9,10 @@ use BigUint;
use Sign::*;
use big_digit::BigDigit;
use bigint::{magnitude, into_magnitude};
use bigint::{into_magnitude, magnitude};
use traits::Zero;
use integer::Integer;
use traits::Zero;
pub trait RandBigInt {
/// Generate a random `BigUint` of the given bit size.
@ -110,7 +110,6 @@ impl<R: Rng + ?Sized> RandBigInt for R {
}
}
/// The back-end implementing rand's `UniformSampler` for `BigUint`.
#[derive(Clone, Debug)]
pub struct UniformBigUint {
@ -151,7 +150,6 @@ impl SampleUniform for BigUint {
type Sampler = UniformBigUint;
}
/// The back-end implementing rand's `UniformSampler` for `BigInt`.
#[derive(Clone, Debug)]
pub struct UniformBigInt {

File diff suppressed because it is too large Load Diff

View File

@ -76,7 +76,6 @@
//! The `num-bigint` crate is tested for rustc 1.15 and greater.
#![doc(html_root_url = "https://docs.rs/num-bigint/0.2")]
// We don't actually support `no_std` yet, and probably won't until `alloc` is stable. We're just
// reserving this ability with the "std" feature now, and compilation will fail without.
#![cfg_attr(not(feature = "std"), no_std)]
@ -95,8 +94,8 @@ use std::fmt;
#[macro_use]
mod macros;
mod biguint;
mod bigint;
mod biguint;
#[cfg(feature = "rand")]
mod bigrand;
@ -159,12 +158,12 @@ impl Error for ParseBigIntError {
pub use biguint::BigUint;
pub use biguint::ToBigUint;
pub use bigint::Sign;
pub use bigint::BigInt;
pub use bigint::Sign;
pub use bigint::ToBigInt;
#[cfg(feature = "rand")]
pub use bigrand::{RandBigInt, RandomBits, UniformBigUint, UniformBigInt};
pub use bigrand::{RandBigInt, RandomBits, UniformBigInt, UniformBigUint};
mod big_digit {
/// A `BigDigit` is a `BigUint`'s composing element.

View File

@ -12,7 +12,7 @@ macro_rules! forward_val_val_binop {
$imp::$method(self, &other)
}
}
}
};
}
macro_rules! forward_val_val_binop_commutative {
@ -30,7 +30,7 @@ macro_rules! forward_val_val_binop_commutative {
}
}
}
}
};
}
macro_rules! forward_ref_val_binop {
@ -44,7 +44,7 @@ macro_rules! forward_ref_val_binop {
$imp::$method(self, &other)
}
}
}
};
}
macro_rules! forward_ref_val_binop_commutative {
@ -58,7 +58,7 @@ macro_rules! forward_ref_val_binop_commutative {
$imp::$method(other, self)
}
}
}
};
}
macro_rules! forward_val_ref_binop {
@ -72,7 +72,7 @@ macro_rules! forward_val_ref_binop {
$imp::$method(&self, other)
}
}
}
};
}
macro_rules! forward_ref_ref_binop {
@ -86,7 +86,7 @@ macro_rules! forward_ref_ref_binop {
$imp::$method(self.clone(), other)
}
}
}
};
}
macro_rules! forward_ref_ref_binop_commutative {
@ -104,7 +104,7 @@ macro_rules! forward_ref_ref_binop_commutative {
}
}
}
}
};
}
macro_rules! forward_val_assign {
@ -115,7 +115,7 @@ macro_rules! forward_val_assign {
self.$method(&other);
}
}
}
};
}
macro_rules! forward_val_assign_scalar {
(impl $imp:ident for $res:ty, $scalar:ty, $method:ident) => {
@ -125,11 +125,11 @@ macro_rules! forward_val_assign_scalar {
self.$method(&other);
}
}
}
};
}
macro_rules! forward_scalar_val_val_binop_commutative {
(impl $imp:ident<$scalar:ty> for $res:ty, $method: ident) => {
(impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
impl $imp<$res> for $scalar {
type Output = $res;
@ -138,11 +138,11 @@ macro_rules! forward_scalar_val_val_binop_commutative {
$imp::$method(other, self)
}
}
}
};
}
macro_rules! forward_scalar_val_ref_binop {
(impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
(impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
impl<'a> $imp<&'a $scalar> for $res {
type Output = $res;
@ -160,11 +160,11 @@ macro_rules! forward_scalar_val_ref_binop {
$imp::$method(*self, other)
}
}
}
};
}
macro_rules! forward_scalar_ref_val_binop {
(impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
(impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
impl<'a> $imp<$scalar> for &'a $res {
type Output = $res;
@ -182,11 +182,11 @@ macro_rules! forward_scalar_ref_val_binop {
$imp::$method(self, other.clone())
}
}
}
};
}
macro_rules! forward_scalar_ref_ref_binop {
(impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
(impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
impl<'a, 'b> $imp<&'b $scalar> for &'a $res {
type Output = $res;
@ -204,7 +204,7 @@ macro_rules! forward_scalar_ref_ref_binop {
$imp::$method(*self, other.clone())
}
}
}
};
}
macro_rules! promote_scalars {
@ -333,11 +333,11 @@ macro_rules! impl_sum_iter_type {
($res:ty) => {
impl<T> Sum<T> for $res
where
$res: Add<T, Output=$res>
$res: Add<T, Output = $res>,
{
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = T>
I: Iterator<Item = T>,
{
iter.fold(Zero::zero(), <$res>::add)
}
@ -349,11 +349,11 @@ macro_rules! impl_product_iter_type {
($res:ty) => {
impl<T> Product<T> for $res
where
$res: Mul<T, Output=$res>
$res: Mul<T, Output = $res>,
{
fn product<I>(iter: I) -> Self
where
I: Iterator<Item = T>
I: Iterator<Item = T>,
{
iter.fold(One::one(), <$res>::mul)
}

View File

@ -5,7 +5,7 @@ use biguint::BigUint;
struct MontyReducer<'a> {
n: &'a BigUint,
n0inv: u32
n0inv: u32,
}
// Calculate the modular inverse of `num`, using Extended GCD.
@ -33,10 +33,12 @@ fn inv_mod_u32(num: u32) -> u32 {
let q = a / b;
let r = a % b;
// 5: (a, b) <- (b, r)
a = b; b = r;
a = b;
b = r;
// 6: (u, w) <- (w, u - qw)
let m = u - w*q;
u = w; w = m;
let m = u - w * q;
u = w;
w = m;
}
assert!(a == 1);
@ -100,7 +102,7 @@ fn monty_sqr(a: BigUint, mr: &MontyReducer) -> BigUint {
monty_redc(&a * &a, mr)
}
pub fn monty_modpow(a: &BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint{
pub fn monty_modpow(a: &BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint {
let mr = MontyReducer::new(modulus);
// Calculate the Montgomery parameter

View File

@ -5,22 +5,22 @@ extern crate num_traits;
extern crate rand;
use num_bigint::BigUint;
use num_bigint::{BigInt, ToBigInt};
use num_bigint::Sign::{Minus, NoSign, Plus};
use num_bigint::{BigInt, ToBigInt};
use std::cmp::Ordering::{Less, Equal, Greater};
use std::{f32, f64};
use std::{i8, i16, i32, i64, isize};
use std::cmp::Ordering::{Equal, Greater, Less};
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hash, Hasher};
use std::iter::repeat;
use std::{u8, u16, u32, u64, usize};
use std::ops::Neg;
use std::{f32, f64};
#[cfg(has_i128)]
use std::{i128, u128};
use std::ops::Neg;
use std::hash::{BuildHasher, Hasher, Hash};
use std::collections::hash_map::RandomState;
use std::{i16, i32, i64, i8, isize};
use std::{u16, u32, u64, u8, usize};
use num_integer::Integer;
use num_traits::{Zero, One, Signed, ToPrimitive, FromPrimitive, Num, Float, Pow};
use num_traits::{Float, FromPrimitive, Num, One, Pow, Signed, ToPrimitive, Zero};
mod consts;
use consts::*;
@ -31,8 +31,10 @@ mod macros;
#[test]
fn test_from_bytes_be() {
fn check(s: &str, result: &str) {
assert_eq!(BigInt::from_bytes_be(Plus, s.as_bytes()),
BigInt::parse_bytes(result.as_bytes(), 10).unwrap());
assert_eq!(
BigInt::from_bytes_be(Plus, s.as_bytes()),
BigInt::parse_bytes(result.as_bytes(), 10).unwrap()
);
}
check("A", "65");
check("AA", "16705");
@ -64,8 +66,10 @@ fn test_to_bytes_be() {
#[test]
fn test_from_bytes_le() {
fn check(s: &str, result: &str) {
assert_eq!(BigInt::from_bytes_le(Plus, s.as_bytes()),
BigInt::parse_bytes(result.as_bytes(), 10).unwrap());
assert_eq!(
BigInt::from_bytes_le(Plus, s.as_bytes()),
BigInt::parse_bytes(result.as_bytes(), 10).unwrap()
);
}
check("A", "65");
check("AA", "16705");
@ -97,8 +101,12 @@ fn test_to_bytes_le() {
#[test]
fn test_to_signed_bytes_le() {
fn check(s: &str, result: Vec<u8>) {
assert_eq!(BigInt::parse_bytes(s.as_bytes(), 10).unwrap().to_signed_bytes_le(),
result);
assert_eq!(
BigInt::parse_bytes(s.as_bytes(), 10)
.unwrap()
.to_signed_bytes_le(),
result
);
}
check("0", vec![0]);
@ -113,8 +121,10 @@ fn test_to_signed_bytes_le() {
#[test]
fn test_from_signed_bytes_le() {
fn check(s: &[u8], result: &str) {
assert_eq!(BigInt::from_signed_bytes_le(s),
BigInt::parse_bytes(result.as_bytes(), 10).unwrap());
assert_eq!(
BigInt::from_signed_bytes_le(s),
BigInt::parse_bytes(result.as_bytes(), 10).unwrap()
);
}
check(&[], "0");
@ -132,8 +142,12 @@ fn test_from_signed_bytes_le() {
#[test]
fn test_to_signed_bytes_be() {
fn check(s: &str, result: Vec<u8>) {
assert_eq!(BigInt::parse_bytes(s.as_bytes(), 10).unwrap().to_signed_bytes_be(),
result);
assert_eq!(
BigInt::parse_bytes(s.as_bytes(), 10)
.unwrap()
.to_signed_bytes_be(),
result
);
}
check("0", vec![0]);
@ -148,8 +162,10 @@ fn test_to_signed_bytes_be() {
#[test]
fn test_from_signed_bytes_be() {
fn check(s: &[u8], result: &str) {
assert_eq!(BigInt::from_signed_bytes_be(s),
BigInt::parse_bytes(result.as_bytes(), 10).unwrap());
assert_eq!(
BigInt::from_signed_bytes_be(s),
BigInt::parse_bytes(result.as_bytes(), 10).unwrap()
);
}
check(&[], "0");
@ -361,8 +377,10 @@ fn test_convert_f32() {
check(&BigInt::from(u16::MAX), 2.0.powi(16) - 1.0);
check(&BigInt::from(1u64 << 32), 2.0.powi(32));
check(&BigInt::from_slice(Plus, &[0, 0, 1]), 2.0.powi(64));
check(&((BigInt::one() << 100) + (BigInt::one() << 123)),
2.0.powi(100) + 2.0.powi(123));
check(
&((BigInt::one() << 100) + (BigInt::one() << 123)),
2.0.powi(100) + 2.0.powi(123),
);
check(&(BigInt::one() << 127), 2.0.powi(127));
check(&(BigInt::from((1u64 << 24) - 1) << (128 - 24)), f32::MAX);
@ -394,14 +412,18 @@ fn test_convert_f32() {
}
// rounding
assert_eq!(BigInt::from_f32(-f32::consts::PI),
Some(BigInt::from(-3i32)));
assert_eq!(
BigInt::from_f32(-f32::consts::PI),
Some(BigInt::from(-3i32))
);
assert_eq!(BigInt::from_f32(-f32::consts::E), Some(BigInt::from(-2i32)));
assert_eq!(BigInt::from_f32(-0.99999), Some(BigInt::zero()));
assert_eq!(BigInt::from_f32(-0.5), Some(BigInt::zero()));
assert_eq!(BigInt::from_f32(-0.0), Some(BigInt::zero()));
assert_eq!(BigInt::from_f32(f32::MIN_POSITIVE / 2.0),
Some(BigInt::zero()));
assert_eq!(
BigInt::from_f32(f32::MIN_POSITIVE / 2.0),
Some(BigInt::zero())
);
assert_eq!(BigInt::from_f32(f32::MIN_POSITIVE), Some(BigInt::zero()));
assert_eq!(BigInt::from_f32(0.5), Some(BigInt::zero()));
assert_eq!(BigInt::from_f32(0.99999), Some(BigInt::zero()));
@ -443,8 +465,10 @@ fn test_convert_f64() {
check(&BigInt::from(u32::MAX), 2.0.powi(32) - 1.0);
check(&BigInt::from(1u64 << 32), 2.0.powi(32));
check(&BigInt::from_slice(Plus, &[0, 0, 1]), 2.0.powi(64));
check(&((BigInt::one() << 100) + (BigInt::one() << 152)),
2.0.powi(100) + 2.0.powi(152));
check(
&((BigInt::one() << 100) + (BigInt::one() << 152)),
2.0.powi(100) + 2.0.powi(152),
);
check(&(BigInt::one() << 1023), 2.0.powi(1023));
check(&(BigInt::from((1u64 << 53) - 1) << (1024 - 53)), f64::MAX);
@ -468,14 +492,18 @@ fn test_convert_f64() {
}
// rounding
assert_eq!(BigInt::from_f64(-f64::consts::PI),
Some(BigInt::from(-3i32)));
assert_eq!(
BigInt::from_f64(-f64::consts::PI),
Some(BigInt::from(-3i32))
);
assert_eq!(BigInt::from_f64(-f64::consts::E), Some(BigInt::from(-2i32)));
assert_eq!(BigInt::from_f64(-0.99999), Some(BigInt::zero()));
assert_eq!(BigInt::from_f64(-0.5), Some(BigInt::zero()));
assert_eq!(BigInt::from_f64(-0.0), Some(BigInt::zero()));
assert_eq!(BigInt::from_f64(f64::MIN_POSITIVE / 2.0),
Some(BigInt::zero()));
assert_eq!(
BigInt::from_f64(f64::MIN_POSITIVE / 2.0),
Some(BigInt::zero())
);
assert_eq!(BigInt::from_f64(f64::MIN_POSITIVE), Some(BigInt::zero()));
assert_eq!(BigInt::from_f64(0.5), Some(BigInt::zero()));
assert_eq!(BigInt::from_f64(0.99999), Some(BigInt::zero()));
@ -533,7 +561,10 @@ fn test_convert_from_uint() {
check!(u32, BigInt::from_slice(Plus, &[u32::MAX]));
check!(u64, BigInt::from_slice(Plus, &[u32::MAX, u32::MAX]));
#[cfg(has_i128)]
check!(u128, BigInt::from_slice(Plus, &[u32::MAX, u32::MAX, u32::MAX, u32::MAX]));
check!(
u128,
BigInt::from_slice(Plus, &[u32::MAX, u32::MAX, u32::MAX, u32::MAX])
);
check!(usize, BigInt::from(usize::MAX as u64));
}
@ -548,36 +579,50 @@ fn test_convert_from_int() {
assert_eq!(BigInt::from($ty::one()), BigInt::one());
assert_eq!(BigInt::from($ty::MAX - $ty::one()), $max - BigInt::one());
assert_eq!(BigInt::from($ty::MAX), $max);
}
};
}
check!(i8,
BigInt::from_slice(Minus, &[1 << 7]),
BigInt::from_slice(Plus, &[i8::MAX as u32]));
check!(i16,
BigInt::from_slice(Minus, &[1 << 15]),
BigInt::from_slice(Plus, &[i16::MAX as u32]));
check!(i32,
BigInt::from_slice(Minus, &[1 << 31]),
BigInt::from_slice(Plus, &[i32::MAX as u32]));
check!(i64,
BigInt::from_slice(Minus, &[0, 1 << 31]),
BigInt::from_slice(Plus, &[u32::MAX, i32::MAX as u32]));
check!(
i8,
BigInt::from_slice(Minus, &[1 << 7]),
BigInt::from_slice(Plus, &[i8::MAX as u32])
);
check!(
i16,
BigInt::from_slice(Minus, &[1 << 15]),
BigInt::from_slice(Plus, &[i16::MAX as u32])
);
check!(
i32,
BigInt::from_slice(Minus, &[1 << 31]),
BigInt::from_slice(Plus, &[i32::MAX as u32])
);
check!(
i64,
BigInt::from_slice(Minus, &[0, 1 << 31]),
BigInt::from_slice(Plus, &[u32::MAX, i32::MAX as u32])
);
#[cfg(has_i128)]
check!(i128,
BigInt::from_slice(Minus, &[0, 0, 0, 1 << 31]),
BigInt::from_slice(Plus, &[u32::MAX, u32::MAX, u32::MAX, i32::MAX as u32]));
check!(isize,
BigInt::from(isize::MIN as i64),
BigInt::from(isize::MAX as i64));
check!(
i128,
BigInt::from_slice(Minus, &[0, 0, 0, 1 << 31]),
BigInt::from_slice(Plus, &[u32::MAX, u32::MAX, u32::MAX, i32::MAX as u32])
);
check!(
isize,
BigInt::from(isize::MIN as i64),
BigInt::from(isize::MAX as i64)
);
}
#[test]
fn test_convert_from_biguint() {
assert_eq!(BigInt::from(BigUint::zero()), BigInt::zero());
assert_eq!(BigInt::from(BigUint::one()), BigInt::one());
assert_eq!(BigInt::from(BigUint::from_slice(&[1, 2, 3])),
BigInt::from_slice(Plus, &[1, 2, 3]));
assert_eq!(
BigInt::from(BigUint::from_slice(&[1, 2, 3])),
BigInt::from_slice(Plus, &[1, 2, 3])
);
}
#[test]
@ -729,7 +774,6 @@ fn test_div_mod_floor() {
}
}
#[test]
fn test_div_rem() {
fn check_sub(a: &BigInt, b: &BigInt, ans_q: &BigInt, ans_r: &BigInt) {
@ -950,7 +994,9 @@ fn test_from_str_radix() {
// issue 10522, this hit an edge case that caused it to
// attempt to allocate a vector of size (-1u) == huge.
let x: BigInt = format!("1{}", repeat("0").take(36).collect::<String>()).parse().unwrap();
let x: BigInt = format!("1{}", repeat("0").take(36).collect::<String>())
.parse()
.unwrap();
let _y = x.to_string();
}
@ -980,8 +1026,10 @@ fn test_binary() {
let hello = BigInt::parse_bytes("-224055342307539".as_bytes(), 10).unwrap();
assert_eq!(format!("{:b}", a), "1010");
assert_eq!(format!("{:b}", hello),
"-110010111100011011110011000101101001100011010011");
assert_eq!(
format!("{:b}", hello),
"-110010111100011011110011000101101001100011010011"
);
assert_eq!(format!("{:♥>+#8b}", a), "♥+0b1010");
}
@ -1024,8 +1072,8 @@ fn test_negative_shr() {
#[test]
#[cfg(feature = "rand")]
fn test_random_shr() {
use rand::Rng;
use rand::distributions::Standard;
use rand::Rng;
let mut rng = rand::thread_rng();
for p in rng.sample_iter::<i64, _>(&Standard).take(1000) {
@ -1066,8 +1114,11 @@ fn test_iter_product() {
FromPrimitive::from_i32(-1004).unwrap(),
FromPrimitive::from_i32(1005).unwrap(),
];
let result = data.get(0).unwrap() * data.get(1).unwrap() * data.get(2).unwrap()
* data.get(3).unwrap() * data.get(4).unwrap();
let result = data.get(0).unwrap()
* data.get(1).unwrap()
* data.get(2).unwrap()
* data.get(3).unwrap()
* data.get(4).unwrap();
assert_eq!(result, data.iter().product());
assert_eq!(result, data.into_iter().product());
@ -1085,8 +1136,10 @@ fn test_iter_sum_generic() {
#[test]
fn test_iter_product_generic() {
let data = vec![1001, -1002, 1003, -1004, 1005];
let result = data[0].to_bigint().unwrap() * data[1].to_bigint().unwrap()
* data[2].to_bigint().unwrap() * data[3].to_bigint().unwrap()
let result = data[0].to_bigint().unwrap()
* data[1].to_bigint().unwrap()
* data[2].to_bigint().unwrap()
* data[3].to_bigint().unwrap()
* data[4].to_bigint().unwrap();
assert_eq!(result, data.iter().product());
@ -1111,7 +1164,7 @@ fn test_pow() {
assert_eq!(minus_two.pow(1 as $t), minus_two, "-2^1");
assert_eq!(minus_two.pow(2 as $t), four, "-2^2");
assert_eq!(minus_two.pow(3 as $t), -&eight, "-2^3");
}
};
}
check!(u8);
check!(u16);

View File

@ -24,41 +24,38 @@ impl ToBigInt for ValueVec {
}
// a, !a
const NOT_VALUES: &'static [(ValueVec, ValueVec)]
= &[(N, M(&[1])),
(P(&[1]), M(&[2])),
(P(&[2]), M(&[3])),
(P(&[!0 - 2]), M(&[!0 - 1])),
(P(&[!0 - 1]), M(&[!0])),
(P(&[!0]), M(&[0, 1])),
(P(&[0, 1]), M(&[1, 1])),
(P(&[1, 1]), M(&[2, 1]))];
const NOT_VALUES: &'static [(ValueVec, ValueVec)] = &[
(N, M(&[1])),
(P(&[1]), M(&[2])),
(P(&[2]), M(&[3])),
(P(&[!0 - 2]), M(&[!0 - 1])),
(P(&[!0 - 1]), M(&[!0])),
(P(&[!0]), M(&[0, 1])),
(P(&[0, 1]), M(&[1, 1])),
(P(&[1, 1]), M(&[2, 1])),
];
// a, b, a & b, a | b, a ^ b
const BITWISE_VALUES: &'static [(ValueVec, ValueVec, ValueVec, ValueVec, ValueVec)]
= &[(N, N, N, N, N),
(N, P(&[1]), N, P(&[1]), P(&[1])),
(N, P(&[!0]), N, P(&[!0]), P(&[!0])),
(N, P(&[0, 1]), N, P(&[0, 1]), P(&[0, 1])),
(N, M(&[1]), N, M(&[1]), M(&[1])),
(N, M(&[!0]), N, M(&[!0]), M(&[!0])),
(N, M(&[0, 1]), N, M(&[0, 1]), M(&[0, 1])),
(P(&[1]), P(&[!0]), P(&[1]), P(&[!0]), P(&[!0 - 1])),
(P(&[!0]), P(&[!0]), P(&[!0]), P(&[!0]), N),
(P(&[!0]), P(&[1, 1]), P(&[1]), P(&[!0, 1]), P(&[!0 - 1, 1])),
(P(&[1]), M(&[!0]), P(&[1]), M(&[!0]), M(&[0, 1])),
(P(&[!0]), M(&[1]), P(&[!0]), M(&[1]), M(&[0, 1])),
(P(&[!0]), M(&[!0]), P(&[1]), M(&[1]), M(&[2])),
(P(&[!0]), M(&[1, 1]), P(&[!0]), M(&[1, 1]), M(&[0, 2])),
(P(&[1, 1]), M(&[!0]), P(&[1, 1]), M(&[!0]), M(&[0, 2])),
(M(&[1]), M(&[!0]), M(&[!0]), M(&[1]), P(&[!0 - 1])),
(M(&[!0]), M(&[!0]), M(&[!0]), M(&[!0]), N),
(M(&[!0]), M(&[1, 1]), M(&[!0, 1]), M(&[1]), P(&[!0 - 1, 1]))];
const BITWISE_VALUES: &'static [(ValueVec, ValueVec, ValueVec, ValueVec, ValueVec)] = &[
(N, N, N, N, N),
(N, P(&[1]), N, P(&[1]), P(&[1])),
(N, P(&[!0]), N, P(&[!0]), P(&[!0])),
(N, P(&[0, 1]), N, P(&[0, 1]), P(&[0, 1])),
(N, M(&[1]), N, M(&[1]), M(&[1])),
(N, M(&[!0]), N, M(&[!0]), M(&[!0])),
(N, M(&[0, 1]), N, M(&[0, 1]), M(&[0, 1])),
(P(&[1]), P(&[!0]), P(&[1]), P(&[!0]), P(&[!0 - 1])),
(P(&[!0]), P(&[!0]), P(&[!0]), P(&[!0]), N),
(P(&[!0]), P(&[1, 1]), P(&[1]), P(&[!0, 1]), P(&[!0 - 1, 1])),
(P(&[1]), M(&[!0]), P(&[1]), M(&[!0]), M(&[0, 1])),
(P(&[!0]), M(&[1]), P(&[!0]), M(&[1]), M(&[0, 1])),
(P(&[!0]), M(&[!0]), P(&[1]), M(&[1]), M(&[2])),
(P(&[!0]), M(&[1, 1]), P(&[!0]), M(&[1, 1]), M(&[0, 2])),
(P(&[1, 1]), M(&[!0]), P(&[1, 1]), M(&[!0]), M(&[0, 2])),
(M(&[1]), M(&[!0]), M(&[!0]), M(&[1]), P(&[!0 - 1])),
(M(&[!0]), M(&[!0]), M(&[!0]), M(&[!0]), N),
(M(&[!0]), M(&[1, 1]), M(&[!0, 1]), M(&[1]), P(&[!0 - 1, 1])),
];
const I32_MIN: i64 = i32::MIN as i64;
const I32_MAX: i64 = i32::MAX as i64;
@ -66,13 +63,50 @@ const U32_MAX: i64 = u32::MAX as i64;
// some corner cases
const I64_VALUES: &'static [i64] = &[
i64::MIN, i64::MIN + 1, i64::MIN + 2, i64::MIN + 3,
-U32_MAX - 3, -U32_MAX - 2, -U32_MAX - 1, -U32_MAX, -U32_MAX + 1, -U32_MAX + 2, -U32_MAX + 3,
I32_MIN - 3, I32_MIN - 2, I32_MIN - 1, I32_MIN, I32_MIN + 1, I32_MIN + 2, I32_MIN + 3,
-3, -2, -1, 0, 1, 2, 3,
I32_MAX - 3, I32_MAX - 2, I32_MAX - 1, I32_MAX, I32_MAX + 1, I32_MAX + 2, I32_MAX + 3,
U32_MAX - 3, U32_MAX - 2, U32_MAX - 1, U32_MAX, U32_MAX + 1, U32_MAX + 2, U32_MAX + 3,
i64::MAX - 3, i64::MAX - 2, i64::MAX - 1, i64::MAX];
i64::MIN,
i64::MIN + 1,
i64::MIN + 2,
i64::MIN + 3,
-U32_MAX - 3,
-U32_MAX - 2,
-U32_MAX - 1,
-U32_MAX,
-U32_MAX + 1,
-U32_MAX + 2,
-U32_MAX + 3,
I32_MIN - 3,
I32_MIN - 2,
I32_MIN - 1,
I32_MIN,
I32_MIN + 1,
I32_MIN + 2,
I32_MIN + 3,
-3,
-2,
-1,
0,
1,
2,
3,
I32_MAX - 3,
I32_MAX - 2,
I32_MAX - 1,
I32_MAX,
I32_MAX + 1,
I32_MAX + 2,
I32_MAX + 3,
U32_MAX - 3,
U32_MAX - 2,
U32_MAX - 1,
U32_MAX,
U32_MAX + 1,
U32_MAX + 2,
U32_MAX + 3,
i64::MAX - 3,
i64::MAX - 2,
i64::MAX - 1,
i64::MAX,
];
#[test]
fn test_not() {

View File

@ -3,7 +3,7 @@ extern crate num_traits;
use num_bigint::BigInt;
use num_bigint::Sign::Plus;
use num_traits::{Zero, Signed, ToPrimitive};
use num_traits::{Signed, ToPrimitive, Zero};
use std::ops::Neg;
@ -142,5 +142,4 @@ fn test_scalar_div_rem() {
check(&a, b, &c, &d);
}
}
}

View File

@ -2,24 +2,26 @@ extern crate num_bigint;
extern crate num_integer;
extern crate num_traits;
use num_integer::Integer;
use num_bigint::{BigUint, ToBigUint};
use num_bigint::{BigInt, ToBigInt};
use num_bigint::Sign::Plus;
use num_bigint::{BigInt, ToBigInt};
use num_bigint::{BigUint, ToBigUint};
use num_integer::Integer;
use std::cmp::Ordering::{Less, Equal, Greater};
use std::{f32, f64};
use std::cmp::Ordering::{Equal, Greater, Less};
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hash, Hasher};
use std::i64;
use std::iter::repeat;
use std::str::FromStr;
use std::{u8, u16, u32, u64, usize};
use std::{f32, f64};
#[cfg(has_i128)]
use std::{i128, u128};
use std::hash::{BuildHasher, Hasher, Hash};
use std::collections::hash_map::RandomState;
use std::{u16, u32, u64, u8, usize};
use num_traits::{Num, Zero, One, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, ToPrimitive,
FromPrimitive, Float, Pow};
use num_traits::{
CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, Float, FromPrimitive, Num, One, Pow,
ToPrimitive, Zero,
};
mod consts;
use consts::*;
@ -30,8 +32,10 @@ mod macros;
#[test]
fn test_from_bytes_be() {
fn check(s: &str, result: &str) {
assert_eq!(BigUint::from_bytes_be(s.as_bytes()),
BigUint::parse_bytes(result.as_bytes(), 10).unwrap());
assert_eq!(
BigUint::from_bytes_be(s.as_bytes()),
BigUint::parse_bytes(result.as_bytes(), 10).unwrap()
);
}
check("A", "65");
check("AA", "16705");
@ -61,8 +65,10 @@ fn test_to_bytes_be() {
#[test]
fn test_from_bytes_le() {
fn check(s: &str, result: &str) {
assert_eq!(BigUint::from_bytes_le(s.as_bytes()),
BigUint::parse_bytes(result.as_bytes(), 10).unwrap());
assert_eq!(
BigUint::from_bytes_le(s.as_bytes()),
BigUint::parse_bytes(result.as_bytes(), 10).unwrap()
);
}
check("A", "65");
check("AA", "16705");
@ -234,115 +240,137 @@ fn test_shl() {
check("0", 3, "0");
check("1", 3, "8");
check("1\
0000\
0000\
0000\
0001\
0000\
0000\
0000\
0001",
3,
"8\
0000\
0000\
0000\
0008\
0000\
0000\
0000\
0008");
check("1\
0000\
0001\
0000\
0001",
2,
"4\
0000\
0004\
0000\
0004");
check("1\
0001\
0001",
1,
"2\
0002\
0002");
check(
"1\
0000\
0000\
0000\
0001\
0000\
0000\
0000\
0001",
3,
"8\
0000\
0000\
0000\
0008\
0000\
0000\
0000\
0008",
);
check(
"1\
0000\
0001\
0000\
0001",
2,
"4\
0000\
0004\
0000\
0004",
);
check(
"1\
0001\
0001",
1,
"2\
0002\
0002",
);
check("\
4000\
0000\
0000\
0000",
3,
"2\
0000\
0000\
0000\
0000");
check("4000\
0000",
2,
"1\
0000\
0000");
check("4000",
2,
"1\
0000");
check(
"\
4000\
0000\
0000\
0000",
3,
"2\
0000\
0000\
0000\
0000",
);
check(
"4000\
0000",
2,
"1\
0000\
0000",
);
check(
"4000",
2,
"1\
0000",
);
check("4000\
0000\
0000\
0000",
67,
"2\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000");
check("4000\
0000",
35,
"2\
0000\
0000\
0000\
0000");
check("4000",
19,
"2\
0000\
0000");
check(
"4000\
0000\
0000\
0000",
67,
"2\
0000\
0000\
0000\
0000\
0000\
0000\
0000\
0000",
);
check(
"4000\
0000",
35,
"2\
0000\
0000\
0000\
0000",
);
check(
"4000",
19,
"2\
0000\
0000",
);
check("fedc\
ba98\
7654\
3210\
fedc\
ba98\
7654\
3210",
4,
"f\
edcb\
a987\
6543\
210f\
edcb\
a987\
6543\
2100");
check("88887777666655554444333322221111",
16,
"888877776666555544443333222211110000");
check(
"fedc\
ba98\
7654\
3210\
fedc\
ba98\
7654\
3210",
4,
"f\
edcb\
a987\
6543\
210f\
edcb\
a987\
6543\
2100",
);
check(
"88887777666655554444333322221111",
16,
"888877776666555544443333222211110000",
);
}
#[test]
@ -359,111 +387,133 @@ fn test_shr() {
check("0", 3, "0");
check("f", 3, "1");
check("1\
0000\
0000\
0000\
0001\
0000\
0000\
0000\
0001",
3,
"2000\
0000\
0000\
0000\
2000\
0000\
0000\
0000");
check("1\
0000\
0001\
0000\
0001",
2,
"4000\
0000\
4000\
0000");
check("1\
0001\
0001",
1,
"8000\
8000");
check(
"1\
0000\
0000\
0000\
0001\
0000\
0000\
0000\
0001",
3,
"2000\
0000\
0000\
0000\
2000\
0000\
0000\
0000",
);
check(
"1\
0000\
0001\
0000\
0001",
2,
"4000\
0000\
4000\
0000",
);
check(
"1\
0001\
0001",
1,
"8000\
8000",
);
check("2\
0000\
0000\
0000\
0001\
0000\
0000\
0000\
0001",
67,
"4000\
0000\
0000\
0000");
check("2\
0000\
0001\
0000\
0001",
35,
"4000\
0000");
check("2\
0001\
0001",
19,
"4000");
check(
"2\
0000\
0000\
0000\
0001\
0000\
0000\
0000\
0001",
67,
"4000\
0000\
0000\
0000",
);
check(
"2\
0000\
0001\
0000\
0001",
35,
"4000\
0000",
);
check(
"2\
0001\
0001",
19,
"4000",
);
check("1\
0000\
0000\
0000\
0000",
1,
"8000\
0000\
0000\
0000");
check("1\
0000\
0000",
1,
"8000\
0000");
check("1\
0000",
1,
"8000");
check("f\
edcb\
a987\
6543\
210f\
edcb\
a987\
6543\
2100",
4,
"fedc\
ba98\
7654\
3210\
fedc\
ba98\
7654\
3210");
check(
"1\
0000\
0000\
0000\
0000",
1,
"8000\
0000\
0000\
0000",
);
check(
"1\
0000\
0000",
1,
"8000\
0000",
);
check(
"1\
0000",
1,
"8000",
);
check(
"f\
edcb\
a987\
6543\
210f\
edcb\
a987\
6543\
2100",
4,
"fedc\
ba98\
7654\
3210\
fedc\
ba98\
7654\
3210",
);
check("888877776666555544443333222211110000",
16,
"88887777666655554444333322221111");
check(
"888877776666555544443333222211110000",
16,
"88887777666655554444333322221111",
);
}
// `DoubleBigDigit` size dependent
@ -577,8 +627,10 @@ fn test_convert_f32() {
check(&BigUint::from(u16::MAX), 2.0.powi(16) - 1.0);
check(&BigUint::from(1u64 << 32), 2.0.powi(32));
check(&BigUint::from_slice(&[0, 0, 1]), 2.0.powi(64));
check(&((BigUint::one() << 100) + (BigUint::one() << 123)),
2.0.powi(100) + 2.0.powi(123));
check(
&((BigUint::one() << 100) + (BigUint::one() << 123)),
2.0.powi(100) + 2.0.powi(123),
);
check(&(BigUint::one() << 127), 2.0.powi(127));
check(&(BigUint::from((1u64 << 24) - 1) << (128 - 24)), f32::MAX);
@ -611,14 +663,18 @@ fn test_convert_f32() {
assert_eq!(BigUint::from_f32(-0.99999), Some(BigUint::zero()));
assert_eq!(BigUint::from_f32(-0.5), Some(BigUint::zero()));
assert_eq!(BigUint::from_f32(-0.0), Some(BigUint::zero()));
assert_eq!(BigUint::from_f32(f32::MIN_POSITIVE / 2.0),
Some(BigUint::zero()));
assert_eq!(
BigUint::from_f32(f32::MIN_POSITIVE / 2.0),
Some(BigUint::zero())
);
assert_eq!(BigUint::from_f32(f32::MIN_POSITIVE), Some(BigUint::zero()));
assert_eq!(BigUint::from_f32(0.5), Some(BigUint::zero()));
assert_eq!(BigUint::from_f32(0.99999), Some(BigUint::zero()));
assert_eq!(BigUint::from_f32(f32::consts::E), Some(BigUint::from(2u32)));
assert_eq!(BigUint::from_f32(f32::consts::PI),
Some(BigUint::from(3u32)));
assert_eq!(
BigUint::from_f32(f32::consts::PI),
Some(BigUint::from(3u32))
);
// special float values
assert_eq!(BigUint::from_f32(f32::NAN), None);
@ -648,8 +704,10 @@ fn test_convert_f64() {
check(&BigUint::from(u32::MAX), 2.0.powi(32) - 1.0);
check(&BigUint::from(1u64 << 32), 2.0.powi(32));
check(&BigUint::from_slice(&[0, 0, 1]), 2.0.powi(64));
check(&((BigUint::one() << 100) + (BigUint::one() << 152)),
2.0.powi(100) + 2.0.powi(152));
check(
&((BigUint::one() << 100) + (BigUint::one() << 152)),
2.0.powi(100) + 2.0.powi(152),
);
check(&(BigUint::one() << 1023), 2.0.powi(1023));
check(&(BigUint::from((1u64 << 53) - 1) << (1024 - 53)), f64::MAX);
@ -677,14 +735,18 @@ fn test_convert_f64() {
assert_eq!(BigUint::from_f64(-0.99999), Some(BigUint::zero()));
assert_eq!(BigUint::from_f64(-0.5), Some(BigUint::zero()));
assert_eq!(BigUint::from_f64(-0.0), Some(BigUint::zero()));
assert_eq!(BigUint::from_f64(f64::MIN_POSITIVE / 2.0),
Some(BigUint::zero()));
assert_eq!(
BigUint::from_f64(f64::MIN_POSITIVE / 2.0),
Some(BigUint::zero())
);
assert_eq!(BigUint::from_f64(f64::MIN_POSITIVE), Some(BigUint::zero()));
assert_eq!(BigUint::from_f64(0.5), Some(BigUint::zero()));
assert_eq!(BigUint::from_f64(0.99999), Some(BigUint::zero()));
assert_eq!(BigUint::from_f64(f64::consts::E), Some(BigUint::from(2u32)));
assert_eq!(BigUint::from_f64(f64::consts::PI),
Some(BigUint::from(3u32)));
assert_eq!(
BigUint::from_f64(f64::consts::PI),
Some(BigUint::from(3u32))
);
// special float values
assert_eq!(BigUint::from_f64(f64::NAN), None);
@ -708,8 +770,10 @@ fn test_convert_to_bigint() {
assert_eq!(n.to_bigint().unwrap().to_biguint().unwrap(), n);
}
check(Zero::zero(), Zero::zero());
check(BigUint::new(vec![1, 2, 3]),
BigInt::from_biguint(Plus, BigUint::new(vec![1, 2, 3])));
check(
BigUint::new(vec![1, 2, 3]),
BigInt::from_biguint(Plus, BigUint::new(vec![1, 2, 3])),
);
}
#[test]
@ -720,7 +784,7 @@ fn test_convert_from_uint() {
assert_eq!(BigUint::from($ty::one()), BigUint::one());
assert_eq!(BigUint::from($ty::MAX - $ty::one()), $max - BigUint::one());
assert_eq!(BigUint::from($ty::MAX), $max);
}
};
}
check!(u8, BigUint::from_slice(&[u8::MAX as u32]));
@ -728,7 +792,10 @@ fn test_convert_from_uint() {
check!(u32, BigUint::from_slice(&[u32::MAX]));
check!(u64, BigUint::from_slice(&[u32::MAX, u32::MAX]));
#[cfg(has_i128)]
check!(u128, BigUint::from_slice(&[u32::MAX, u32::MAX, u32::MAX, u32::MAX]));
check!(
u128,
BigUint::from_slice(&[u32::MAX, u32::MAX, u32::MAX, u32::MAX])
);
check!(usize, BigUint::from(usize::MAX as u64));
}
@ -974,69 +1041,113 @@ fn test_is_even() {
fn to_str_pairs() -> Vec<(BigUint, Vec<(u32, String)>)> {
let bits = 32;
vec![(Zero::zero(),
vec![(2, "0".to_string()), (3, "0".to_string())]),
(BigUint::from_slice(&[0xff]),
vec![(2, "11111111".to_string()),
(3, "100110".to_string()),
(4, "3333".to_string()),
(5, "2010".to_string()),
(6, "1103".to_string()),
(7, "513".to_string()),
(8, "377".to_string()),
(9, "313".to_string()),
(10, "255".to_string()),
(11, "212".to_string()),
(12, "193".to_string()),
(13, "168".to_string()),
(14, "143".to_string()),
(15, "120".to_string()),
(16, "ff".to_string())]),
(BigUint::from_slice(&[0xfff]),
vec![(2, "111111111111".to_string()),
(4, "333333".to_string()),
(16, "fff".to_string())]),
(BigUint::from_slice(&[1, 2]),
vec![(2,
format!("10{}1", repeat("0").take(bits - 1).collect::<String>())),
(4,
format!("2{}1", repeat("0").take(bits / 2 - 1).collect::<String>())),
(10,
match bits {
64 => "36893488147419103233".to_string(),
32 => "8589934593".to_string(),
16 => "131073".to_string(),
_ => panic!(),
}),
(16,
format!("2{}1", repeat("0").take(bits / 4 - 1).collect::<String>()))]),
(BigUint::from_slice(&[1, 2, 3]),
vec![(2,
format!("11{}10{}1",
vec![
(
Zero::zero(),
vec![(2, "0".to_string()), (3, "0".to_string())],
),
(
BigUint::from_slice(&[0xff]),
vec![
(2, "11111111".to_string()),
(3, "100110".to_string()),
(4, "3333".to_string()),
(5, "2010".to_string()),
(6, "1103".to_string()),
(7, "513".to_string()),
(8, "377".to_string()),
(9, "313".to_string()),
(10, "255".to_string()),
(11, "212".to_string()),
(12, "193".to_string()),
(13, "168".to_string()),
(14, "143".to_string()),
(15, "120".to_string()),
(16, "ff".to_string()),
],
),
(
BigUint::from_slice(&[0xfff]),
vec![
(2, "111111111111".to_string()),
(4, "333333".to_string()),
(16, "fff".to_string()),
],
),
(
BigUint::from_slice(&[1, 2]),
vec![
(
2,
format!("10{}1", repeat("0").take(bits - 1).collect::<String>()),
),
(
4,
format!("2{}1", repeat("0").take(bits / 2 - 1).collect::<String>()),
),
(
10,
match bits {
64 => "36893488147419103233".to_string(),
32 => "8589934593".to_string(),
16 => "131073".to_string(),
_ => panic!(),
},
),
(
16,
format!("2{}1", repeat("0").take(bits / 4 - 1).collect::<String>()),
),
],
),
(
BigUint::from_slice(&[1, 2, 3]),
vec![
(
2,
format!(
"11{}10{}1",
repeat("0").take(bits - 2).collect::<String>(),
repeat("0").take(bits - 1).collect::<String>())),
(4,
format!("3{}2{}1",
repeat("0").take(bits - 1).collect::<String>()
),
),
(
4,
format!(
"3{}2{}1",
repeat("0").take(bits / 2 - 1).collect::<String>(),
repeat("0").take(bits / 2 - 1).collect::<String>())),
(8,
match bits {
64 => "14000000000000000000004000000000000000000001".to_string(),
32 => "6000000000100000000001".to_string(),
16 => "140000400001".to_string(),
_ => panic!(),
}),
(10,
match bits {
64 => "1020847100762815390427017310442723737601".to_string(),
32 => "55340232229718589441".to_string(),
16 => "12885032961".to_string(),
_ => panic!(),
}),
(16,
format!("3{}2{}1",
repeat("0").take(bits / 2 - 1).collect::<String>()
),
),
(
8,
match bits {
64 => "14000000000000000000004000000000000000000001".to_string(),
32 => "6000000000100000000001".to_string(),
16 => "140000400001".to_string(),
_ => panic!(),
},
),
(
10,
match bits {
64 => "1020847100762815390427017310442723737601".to_string(),
32 => "55340232229718589441".to_string(),
16 => "12885032961".to_string(),
_ => panic!(),
},
),
(
16,
format!(
"3{}2{}1",
repeat("0").take(bits / 4 - 1).collect::<String>(),
repeat("0").take(bits / 4 - 1).collect::<String>()))])]
repeat("0").take(bits / 4 - 1).collect::<String>()
),
),
],
),
]
}
#[test]
@ -1053,20 +1164,48 @@ fn test_to_str_radix() {
#[test]
fn test_from_and_to_radix() {
const GROUND_TRUTH : &'static[(&'static[u8], u32, &'static[u8])] = &[
(b"0", 42, &[0]),
(b"ffffeeffbb", 2, &[1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1]),
(b"ffffeeffbb", 3, &[2, 2, 1, 1, 2, 1, 1, 2, 0, 0, 0, 0, 0, 1, 2,
0, 0, 0, 0, 1, 0, 0, 2, 2, 0, 1]),
(b"ffffeeffbb", 4, &[3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, 3, 3,
3, 3, 3, 3, 3]),
(b"ffffeeffbb", 5, &[0, 4, 3, 3, 1, 4, 2, 4, 1, 4, 4, 2, 3, 0, 0,
1, 2, 1]),
(b"ffffeeffbb", 6, &[5, 5, 4, 5, 5, 0, 0, 1, 2, 5, 3, 0, 1, 0, 2, 2]),
(b"ffffeeffbb", 7, &[4, 2, 3, 6, 0, 1, 6, 1, 6, 2, 0, 3, 2, 4, 1]),
(b"ffffeeffbb", 8, &[3, 7, 6, 7, 7, 5, 3, 7, 7, 7, 7, 7, 7, 1]),
const GROUND_TRUTH: &'static [(&'static [u8], u32, &'static [u8])] = &[
(b"0", 42, &[0]),
(
b"ffffeeffbb",
2,
&[
1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
],
),
(
b"ffffeeffbb",
3,
&[
2, 2, 1, 1, 2, 1, 1, 2, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 1, 0, 0, 2, 2, 0, 1,
],
),
(
b"ffffeeffbb",
4,
&[3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3],
),
(
b"ffffeeffbb",
5,
&[0, 4, 3, 3, 1, 4, 2, 4, 1, 4, 4, 2, 3, 0, 0, 1, 2, 1],
),
(
b"ffffeeffbb",
6,
&[5, 5, 4, 5, 5, 0, 0, 1, 2, 5, 3, 0, 1, 0, 2, 2],
),
(
b"ffffeeffbb",
7,
&[4, 2, 3, 6, 0, 1, 6, 1, 6, 2, 0, 3, 2, 4, 1],
),
(
b"ffffeeffbb",
8,
&[3, 7, 6, 7, 7, 5, 3, 7, 7, 7, 7, 7, 7, 1],
),
(b"ffffeeffbb", 9, &[8, 4, 5, 7, 0, 0, 3, 2, 0, 3, 0, 8, 3]),
(b"ffffeeffbb", 10, &[5, 9, 5, 3, 1, 5, 0, 1, 5, 9, 9, 0, 1]),
(b"ffffeeffbb", 11, &[10, 7, 6, 5, 2, 0, 3, 3, 3, 4, 9, 3]),
@ -1326,14 +1465,20 @@ fn test_from_and_to_radix() {
inbase_be.reverse(); // now le
assert_eq!(inbase_be, inbaseradix_le);
// from_radix_le
assert_eq!(BigUint::from_radix_le(inbaseradix_le, radix).unwrap(), bigint);
assert_eq!(
BigUint::from_radix_le(inbaseradix_le, radix).unwrap(),
bigint
);
// from_radix_be
let mut inbaseradix_be = Vec::from(inbaseradix_le);
inbaseradix_be.reverse();
assert_eq!(BigUint::from_radix_be(&inbaseradix_be, radix).unwrap(), bigint);
assert_eq!(
BigUint::from_radix_be(&inbaseradix_be, radix).unwrap(),
bigint
);
}
assert!(BigUint::from_radix_le(&[10,100,10], 50).is_none());
assert!(BigUint::from_radix_le(&[10, 100, 10], 50).is_none());
}
#[test]
@ -1410,8 +1555,10 @@ fn test_binary() {
let hello = BigUint::parse_bytes("224055342307539".as_bytes(), 10).unwrap();
assert_eq!(format!("{:b}", a), "1010");
assert_eq!(format!("{:b}", hello),
"110010111100011011110011000101101001100011010011");
assert_eq!(
format!("{:b}", hello),
"110010111100011011110011000101101001100011010011"
);
assert_eq!(format!("{:♥>+#8b}", a), "♥+0b1010");
}
@ -1504,8 +1651,11 @@ fn test_iter_product() {
FromPrimitive::from_u32(1004).unwrap(),
FromPrimitive::from_u32(1005).unwrap(),
];
let result = data.get(0).unwrap() * data.get(1).unwrap() * data.get(2).unwrap()
* data.get(3).unwrap() * data.get(4).unwrap();
let result = data.get(0).unwrap()
* data.get(1).unwrap()
* data.get(2).unwrap()
* data.get(3).unwrap()
* data.get(4).unwrap();
assert_eq!(result, data.iter().product());
assert_eq!(result, data.into_iter().product());
@ -1523,8 +1673,10 @@ fn test_iter_sum_generic() {
#[test]
fn test_iter_product_generic() {
let data = vec![1001_u32, 1002, 1003, 1004, 1005];
let result = data[0].to_biguint().unwrap() * data[1].to_biguint().unwrap()
* data[2].to_biguint().unwrap() * data[3].to_biguint().unwrap()
let result = data[0].to_biguint().unwrap()
* data[1].to_biguint().unwrap()
* data[2].to_biguint().unwrap()
* data[3].to_biguint().unwrap()
* data[4].to_biguint().unwrap();
assert_eq!(result, data.iter().product());
@ -1548,7 +1700,7 @@ fn test_pow() {
assert_eq!(two.pow(10 as $t), tentwentyfour);
assert_eq!(two.pow(11 as $t), twentyfourtyeight);
assert_eq!(two.pow(&(11 as $t)), twentyfourtyeight);
}
};
}
check!(u8);
check!(u16);

View File

@ -2,7 +2,7 @@ extern crate num_bigint;
extern crate num_traits;
use num_bigint::BigUint;
use num_traits::{Zero, ToPrimitive};
use num_traits::{ToPrimitive, Zero};
mod consts;
use consts::*;

View File

@ -3,11 +3,7 @@
pub const N1: u32 = -1i32 as u32;
pub const N2: u32 = -2i32 as u32;
pub const SUM_TRIPLES: &'static [(
&'static [u32],
&'static [u32],
&'static [u32],
)] = &[
pub const SUM_TRIPLES: &'static [(&'static [u32], &'static [u32], &'static [u32])] = &[
(&[], &[], &[]),
(&[], &[1], &[1]),
(&[1], &[1], &[2]),
@ -20,11 +16,7 @@ pub const SUM_TRIPLES: &'static [(
];
pub const M: u32 = ::std::u32::MAX;
pub const MUL_TRIPLES: &'static [(
&'static [u32],
&'static [u32],
&'static [u32],
)] = &[
pub const MUL_TRIPLES: &'static [(&'static [u32], &'static [u32], &'static [u32])] = &[
(&[], &[], &[]),
(&[], &[1], &[]),
(&[2], &[], &[]),

View File

@ -12,15 +12,13 @@ macro_rules! assert_op {
/// Assert that an assign-op works for all val/ref combinations
macro_rules! assert_assign_op {
($left:ident $op:tt $right:ident == $expected:expr) => {
{
let mut left = $left.clone();
assert_eq!({ left $op &$right; left}, $expected);
($left:ident $op:tt $right:ident == $expected:expr) => {{
let mut left = $left.clone();
assert_eq!({ left $op &$right; left}, $expected);
let mut left = $left.clone();
assert_eq!({ left $op $right.clone(); left}, $expected);
}
};
let mut left = $left.clone();
assert_eq!({ left $op $right.clone(); left}, $expected);
}};
}
/// Assert that an op works for scalar left or right

View File

@ -3,58 +3,58 @@ extern crate num_integer;
extern crate num_traits;
static BIG_B: &'static str = "\
efac3c0a_0de55551_fee0bfe4_67fa017a_1a898fa1_6ca57cb1\
ca9e3248_cacc09a9_b99d6abc_38418d0f_82ae4238_d9a68832\
aadec7c1_ac5fed48_7a56a71b_67ac59d5_afb28022_20d9592d\
247c4efc_abbd9b75_586088ee_1dc00dc4_232a8e15_6e8191dd\
675b6ae0_c80f5164_752940bc_284b7cee_885c1e10_e495345b\
8fbe9cfd_e5233fe1_19459d0b_d64be53c_27de5a02_a829976b\
33096862_82dad291_bd38b6a9_be396646_ddaf8039_a2573c39\
1b14e8bc_2cb53e48_298c047e_d9879e9c_5a521076_f0e27df3\
990e1659_d3d8205b_6443ebc0_9918ebee_6764f668_9f2b2be3\
b59cbc76_d76d0dfc_d737c3ec_0ccf9c00_ad0554bf_17e776ad\
b4edf9cc_6ce540be_76229093_5c53893b";
efac3c0a_0de55551_fee0bfe4_67fa017a_1a898fa1_6ca57cb1\
ca9e3248_cacc09a9_b99d6abc_38418d0f_82ae4238_d9a68832\
aadec7c1_ac5fed48_7a56a71b_67ac59d5_afb28022_20d9592d\
247c4efc_abbd9b75_586088ee_1dc00dc4_232a8e15_6e8191dd\
675b6ae0_c80f5164_752940bc_284b7cee_885c1e10_e495345b\
8fbe9cfd_e5233fe1_19459d0b_d64be53c_27de5a02_a829976b\
33096862_82dad291_bd38b6a9_be396646_ddaf8039_a2573c39\
1b14e8bc_2cb53e48_298c047e_d9879e9c_5a521076_f0e27df3\
990e1659_d3d8205b_6443ebc0_9918ebee_6764f668_9f2b2be3\
b59cbc76_d76d0dfc_d737c3ec_0ccf9c00_ad0554bf_17e776ad\
b4edf9cc_6ce540be_76229093_5c53893b";
static BIG_E: &'static str = "\
be0e6ea6_08746133_e0fbc1bf_82dba91e_e2b56231_a81888d2\
a833a1fc_f7ff002a_3c486a13_4f420bf3_a5435be9_1a5c8391\
774d6e6c_085d8357_b0c97d4d_2bb33f7c_34c68059_f78d2541\
eacc8832_426f1816_d3be001e_b69f9242_51c7708e_e10efe98\
449c9a4a_b55a0f23_9d797410_515da00d_3ea07970_4478a2ca\
c3d5043c_bd9be1b4_6dce479d_4302d344_84a939e6_0ab5ada7\
12ae34b2_30cc473c_9f8ee69d_2cac5970_29f5bf18_bc8203e4\
f3e895a2_13c94f1e_24c73d77_e517e801_53661fdd_a2ce9e47\
a73dd7f8_2f2adb1e_3f136bf7_8ae5f3b8_08730de1_a4eff678\
e77a06d0_19a522eb_cbefba2a_9caf7736_b157c5c6_2d192591\
17946850_2ddb1822_117b68a0_32f7db88";
be0e6ea6_08746133_e0fbc1bf_82dba91e_e2b56231_a81888d2\
a833a1fc_f7ff002a_3c486a13_4f420bf3_a5435be9_1a5c8391\
774d6e6c_085d8357_b0c97d4d_2bb33f7c_34c68059_f78d2541\
eacc8832_426f1816_d3be001e_b69f9242_51c7708e_e10efe98\
449c9a4a_b55a0f23_9d797410_515da00d_3ea07970_4478a2ca\
c3d5043c_bd9be1b4_6dce479d_4302d344_84a939e6_0ab5ada7\
12ae34b2_30cc473c_9f8ee69d_2cac5970_29f5bf18_bc8203e4\
f3e895a2_13c94f1e_24c73d77_e517e801_53661fdd_a2ce9e47\
a73dd7f8_2f2adb1e_3f136bf7_8ae5f3b8_08730de1_a4eff678\
e77a06d0_19a522eb_cbefba2a_9caf7736_b157c5c6_2d192591\
17946850_2ddb1822_117b68a0_32f7db88";
// This modulus is the prime from the 2048-bit MODP DH group:
// https://tools.ietf.org/html/rfc3526#section-3
static BIG_M: &'static str = "\
FFFFFFFF_FFFFFFFF_C90FDAA2_2168C234_C4C6628B_80DC1CD1\
29024E08_8A67CC74_020BBEA6_3B139B22_514A0879_8E3404DD\
EF9519B3_CD3A431B_302B0A6D_F25F1437_4FE1356D_6D51C245\
E485B576_625E7EC6_F44C42E9_A637ED6B_0BFF5CB6_F406B7ED\
EE386BFB_5A899FA5_AE9F2411_7C4B1FE6_49286651_ECE45B3D\
C2007CB8_A163BF05_98DA4836_1C55D39A_69163FA8_FD24CF5F\
83655D23_DCA3AD96_1C62F356_208552BB_9ED52907_7096966D\
670C354E_4ABC9804_F1746C08_CA18217C_32905E46_2E36CE3B\
E39E772C_180E8603_9B2783A2_EC07A28F_B5C55DF0_6F4C52C9\
DE2BCBF6_95581718_3995497C_EA956AE5_15D22618_98FA0510\
15728E5A_8AACAA68_FFFFFFFF_FFFFFFFF";
FFFFFFFF_FFFFFFFF_C90FDAA2_2168C234_C4C6628B_80DC1CD1\
29024E08_8A67CC74_020BBEA6_3B139B22_514A0879_8E3404DD\
EF9519B3_CD3A431B_302B0A6D_F25F1437_4FE1356D_6D51C245\
E485B576_625E7EC6_F44C42E9_A637ED6B_0BFF5CB6_F406B7ED\
EE386BFB_5A899FA5_AE9F2411_7C4B1FE6_49286651_ECE45B3D\
C2007CB8_A163BF05_98DA4836_1C55D39A_69163FA8_FD24CF5F\
83655D23_DCA3AD96_1C62F356_208552BB_9ED52907_7096966D\
670C354E_4ABC9804_F1746C08_CA18217C_32905E46_2E36CE3B\
E39E772C_180E8603_9B2783A2_EC07A28F_B5C55DF0_6F4C52C9\
DE2BCBF6_95581718_3995497C_EA956AE5_15D22618_98FA0510\
15728E5A_8AACAA68_FFFFFFFF_FFFFFFFF";
static BIG_R: &'static str = "\
a1468311_6e56edc9_7a98228b_5e924776_0dd7836e_caabac13\
eda5373b_4752aa65_a1454850_40dc770e_30aa8675_6be7d3a8\
9d3085e4_da5155cf_b451ef62_54d0da61_cf2b2c87_f495e096\
055309f7_77802bbb_37271ba8_1313f1b5_075c75d1_024b6c77\
fdb56f17_b05bce61_e527ebfd_2ee86860_e9907066_edd526e7\
93d289bf_6726b293_41b0de24_eff82424_8dfd374b_4ec59542\
35ced2b2_6b195c90_10042ffb_8f58ce21_bc10ec42_64fda779\
d352d234_3d4eaea6_a86111ad_a37e9555_43ca78ce_2885bed7\
5a30d182_f1cf6834_dc5b6e27_1a41ac34_a2e91e11_33363ff0\
f88a7b04_900227c9_f6e6d06b_7856b4bb_4e354d61_060db6c8\
109c4735_6e7db425_7b5d74c7_0b709508";
a1468311_6e56edc9_7a98228b_5e924776_0dd7836e_caabac13\
eda5373b_4752aa65_a1454850_40dc770e_30aa8675_6be7d3a8\
9d3085e4_da5155cf_b451ef62_54d0da61_cf2b2c87_f495e096\
055309f7_77802bbb_37271ba8_1313f1b5_075c75d1_024b6c77\
fdb56f17_b05bce61_e527ebfd_2ee86860_e9907066_edd526e7\
93d289bf_6726b293_41b0de24_eff82424_8dfd374b_4ec59542\
35ced2b2_6b195c90_10042ffb_8f58ce21_bc10ec42_64fda779\
d352d234_3d4eaea6_a86111ad_a37e9555_43ca78ce_2885bed7\
5a30d182_f1cf6834_dc5b6e27_1a41ac34_a2e91e11_33363ff0\
f88a7b04_900227c9_f6e6d06b_7856b4bb_4e354d61_060db6c8\
109c4735_6e7db425_7b5d74c7_0b709508";
mod biguint {
use num_bigint::BigUint;
@ -102,7 +102,7 @@ mod biguint {
mod bigint {
use num_bigint::BigInt;
use num_integer::Integer;
use num_traits::{Num, Zero, One, Signed};
use num_traits::{Num, One, Signed, Zero};
fn check_modpow<T: Into<BigInt>>(b: T, e: T, m: T, r: T) {
fn check(b: &BigInt, e: &BigInt, m: &BigInt, r: &BigInt) {

View File

@ -7,9 +7,9 @@ extern crate rand;
mod biguint {
use num_bigint::{BigUint, RandBigInt, RandomBits};
use num_traits::Zero;
use rand::distributions::Uniform;
use rand::thread_rng;
use rand::{Rng, SeedableRng};
use rand::distributions::Uniform;
#[test]
fn test_rand() {
@ -164,9 +164,9 @@ mod biguint {
mod bigint {
use num_bigint::{BigInt, RandBigInt, RandomBits};
use num_traits::Zero;
use rand::distributions::Uniform;
use rand::thread_rng;
use rand::{Rng, SeedableRng};
use rand::distributions::Uniform;
#[test]
fn test_rand() {

View File

@ -58,7 +58,7 @@ mod biguint {
mod bigint {
use num_bigint::BigInt;
use num_traits::{Signed, Pow};
use num_traits::{Pow, Signed};
fn check(x: i64, n: u32) {
let big_x = BigInt::from(x);

View File

@ -9,7 +9,6 @@ use num_traits::Zero;
use rand::prelude::*;
fn test_mul_divide_torture_count(count: usize) {
let bits_max = 1 << 12;
let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
let mut rng = SmallRng::from_seed(seed);
@ -42,4 +41,3 @@ fn test_mul_divide_torture() {
fn test_mul_divide_torture_long() {
test_mul_divide_torture_count(1000000);
}