chore: run rustfmt on all code
This commit is contained in:
parent
2e198752dc
commit
f7e8af05a4
@ -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) {
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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()
|
||||
};
|
||||
|
@ -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() {
|
||||
|
247
src/bigint.rs
247
src/bigint.rs
@ -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) {
|
||||
|
@ -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 {
|
||||
|
1135
src/biguint.rs
1135
src/biguint.rs
File diff suppressed because it is too large
Load Diff
@ -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.
|
||||
|
@ -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)
|
||||
}
|
||||
|
12
src/monty.rs
12
src/monty.rs
@ -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
|
||||
|
183
tests/bigint.rs
183
tests/bigint.rs
@ -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);
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
796
tests/biguint.rs
796
tests/biguint.rs
@ -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);
|
||||
|
@ -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::*;
|
||||
|
@ -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], &[], &[]),
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user