Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4f92ac7

Browse files
committedJul 12, 2016
Drop some dependencies on BigDigit's size
Before: test divide_0 ... bench: 1,011 ns/iter (+/- 184) test divide_1 ... bench: 18,535 ns/iter (+/- 770) test divide_2 ... bench: 990,467 ns/iter (+/- 91,980) test fac_to_string ... bench: 1,275 ns/iter (+/- 60) test factorial_100 ... bench: 6,453 ns/iter (+/- 101) test fib_100 ... bench: 1,142 ns/iter (+/- 99) test fib_1000 ... bench: 18,713 ns/iter (+/- 2,172) test fib_10000 ... bench: 1,197,965 ns/iter (+/- 21,178) test fib_to_string ... bench: 225 ns/iter (+/- 13) test from_str_radix_02 ... bench: 3,460 ns/iter (+/- 626) test from_str_radix_08 ... bench: 1,324 ns/iter (+/- 24) test from_str_radix_10 ... bench: 1,488 ns/iter (+/- 19) test from_str_radix_16 ... bench: 969 ns/iter (+/- 22) test from_str_radix_36 ... bench: 1,135 ns/iter (+/- 23) test hash ... bench: 102,126 ns/iter (+/- 1,016) test multiply_0 ... bench: 353 ns/iter (+/- 74) test multiply_1 ... bench: 31,006 ns/iter (+/- 679) test multiply_2 ... bench: 3,438,143 ns/iter (+/- 47,640) test pow_bench ... bench: 7,457,045 ns/iter (+/- 96,175) test shl ... bench: 5,627 ns/iter (+/- 121) test shr ... bench: 5,054 ns/iter (+/- 112) test to_str_radix_02 ... bench: 2,774 ns/iter (+/- 88) test to_str_radix_08 ... bench: 980 ns/iter (+/- 425) test to_str_radix_10 ... bench: 3,029 ns/iter (+/- 115) test to_str_radix_16 ... bench: 788 ns/iter (+/- 14) test to_str_radix_36 ... bench: 8,285 ns/iter (+/- 175) After: test divide_0 ... bench: 925 ns/iter (+/- 30) test divide_1 ... bench: 17,660 ns/iter (+/- 379) test divide_2 ... bench: 972,427 ns/iter (+/- 7,560) test fac_to_string ... bench: 1,260 ns/iter (+/- 36) test factorial_100 ... bench: 7,077 ns/iter (+/- 204) test fib_100 ... bench: 1,124 ns/iter (+/- 32) test fib_1000 ... bench: 18,475 ns/iter (+/- 166) test fib_10000 ... bench: 1,192,748 ns/iter (+/- 27,128) test fib_to_string ... bench: 228 ns/iter (+/- 10) test from_str_radix_02 ... bench: 3,379 ns/iter (+/- 74) test from_str_radix_08 ... bench: 1,355 ns/iter (+/- 24) test from_str_radix_10 ... bench: 1,470 ns/iter (+/- 20) test from_str_radix_16 ... bench: 958 ns/iter (+/- 239) test from_str_radix_36 ... bench: 1,137 ns/iter (+/- 19) test hash ... bench: 102,730 ns/iter (+/- 39,897) test multiply_0 ... bench: 351 ns/iter (+/- 15) test multiply_1 ... bench: 31,139 ns/iter (+/- 1,053) test multiply_2 ... bench: 3,464,509 ns/iter (+/- 124,235) test pow_bench ... bench: 7,448,428 ns/iter (+/- 326,903) test shl ... bench: 5,784 ns/iter (+/- 190) test shr ... bench: 4,820 ns/iter (+/- 63) test to_str_radix_02 ... bench: 2,757 ns/iter (+/- 33) test to_str_radix_08 ... bench: 989 ns/iter (+/- 67) test to_str_radix_10 ... bench: 3,045 ns/iter (+/- 70) test to_str_radix_16 ... bench: 787 ns/iter (+/- 24) test to_str_radix_36 ... bench: 8,257 ns/iter (+/- 117)
1 parent 7fcd5f7 commit 4f92ac7

File tree

1 file changed

+225
-150
lines changed

1 file changed

+225
-150
lines changed
 

‎bigint/src/lib.rs

+225-150
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ pub mod big_digit {
127127

128128
// `DoubleBigDigit` size dependent
129129
pub const BITS: usize = 32;
130+
pub use ::std::u32::MAX;
130131

131132
pub const BASE: DoubleBigDigit = 1 << BITS;
132133
const LO_MASK: DoubleBigDigit = (-1i32 as DoubleBigDigit) >> BITS;
@@ -306,7 +307,8 @@ impl FromStr for BigUint {
306307
}
307308
}
308309

309-
// Read bitwise digits that evenly divide BigDigit
310+
// Convert from a power of two radix (bits == ilog2(radix)) where bits evenly divides
311+
// BigDigit::BITS
310312
fn from_bitwise_digits_le(v: &[u8], bits: usize) -> BigUint {
311313
debug_assert!(!v.is_empty() && bits <= 8 && big_digit::BITS % bits == 0);
312314
debug_assert!(v.iter().all(|&c| (c as BigDigit) < (1 << bits)));
@@ -315,14 +317,15 @@ fn from_bitwise_digits_le(v: &[u8], bits: usize) -> BigUint {
315317

316318
let data = v.chunks(digits_per_big_digit)
317319
.map(|chunk| {
318-
chunk.iter().rev().fold(0u32, |acc, &c| (acc << bits) | c as BigDigit)
320+
chunk.iter().rev().fold(0, |acc, &c| (acc << bits) | c as BigDigit)
319321
})
320322
.collect();
321323

322324
BigUint::new(data)
323325
}
324326

325-
// Read bitwise digits that don't evenly divide BigDigit
327+
// Convert from a power of two radix (bits == ilog2(radix)) where bits doesn't evenly divide
328+
// BigDigit::BITS
326329
fn from_inexact_bitwise_digits_le(v: &[u8], bits: usize) -> BigUint {
327330
debug_assert!(!v.is_empty() && bits <= 8 && big_digit::BITS % bits != 0);
328331
debug_assert!(v.iter().all(|&c| (c as BigDigit) < (1 << bits)));
@@ -333,13 +336,13 @@ fn from_inexact_bitwise_digits_le(v: &[u8], bits: usize) -> BigUint {
333336
let mut d = 0;
334337
let mut dbits = 0;
335338
for &c in v {
336-
d |= (c as DoubleBigDigit) << dbits;
339+
d |= (c as BigDigit) << dbits;
337340
dbits += bits;
341+
338342
if dbits >= big_digit::BITS {
339-
let (hi, lo) = big_digit::from_doublebigdigit(d);
340-
data.push(lo);
341-
d = hi as DoubleBigDigit;
343+
data.push(d);
342344
dbits -= big_digit::BITS;
345+
d = (c as BigDigit) >> (bits - dbits);
343346
}
344347
}
345348

@@ -362,8 +365,7 @@ fn from_radix_digits_be(v: &[u8], radix: u32) -> BigUint {
362365
let mut data = Vec::with_capacity(big_digits as usize);
363366

364367
let (base, power) = get_radix_base(radix);
365-
debug_assert!(base < (1 << 32));
366-
let base = base as BigDigit;
368+
let radix = radix as BigDigit;
367369

368370
let r = v.len() % power;
369371
let i = if r == 0 {
@@ -1349,6 +1351,40 @@ impl Integer for BigUint {
13491351
}
13501352
}
13511353

1354+
fn high_bits_to_u64(v: &BigUint) -> u64 {
1355+
match v.data.len() {
1356+
0 => 0,
1357+
1 => v.data[0] as u64,
1358+
_ => {
1359+
let mut bits = v.bits();
1360+
let mut ret = 0u64;
1361+
let mut ret_bits = 0;
1362+
1363+
for d in v.data.iter().rev() {
1364+
let digit_bits = ((bits - 1) & (big_digit::BITS - 1)) + 1;
1365+
let bits_want = cmp::min(64 - ret_bits, digit_bits);
1366+
1367+
if bits_want != 64 {
1368+
ret <<= bits_want;
1369+
}
1370+
ret |= *d as u64 >> (digit_bits - bits_want);
1371+
ret_bits += bits_want;
1372+
bits -= bits_want;
1373+
1374+
if ret_bits == 64 {
1375+
break;
1376+
}
1377+
}
1378+
1379+
ret
1380+
}
1381+
}
1382+
}
1383+
1384+
fn ilog2(v: u64) -> usize {
1385+
(64 - v.leading_zeros()) as usize
1386+
}
1387+
13521388
impl ToPrimitive for BigUint {
13531389
#[inline]
13541390
fn to_i64(&self) -> Option<i64> {
@@ -1362,76 +1398,53 @@ impl ToPrimitive for BigUint {
13621398
})
13631399
}
13641400

1365-
// `DoubleBigDigit` size dependent
13661401
#[inline]
13671402
fn to_u64(&self) -> Option<u64> {
1368-
match self.data.len() {
1369-
0 => Some(0),
1370-
1 => Some(self.data[0] as u64),
1371-
2 => Some(big_digit::to_doublebigdigit(self.data[1], self.data[0]) as u64),
1372-
_ => None,
1403+
let mut ret: u64 = 0;
1404+
let mut bits = 0;
1405+
1406+
for i in self.data.iter() {
1407+
if bits >= 64 {
1408+
return None;
1409+
}
1410+
1411+
ret += (*i as u64) << bits;
1412+
bits += big_digit::BITS;
13731413
}
1414+
1415+
Some(ret)
13741416
}
13751417

1376-
// `DoubleBigDigit` size dependent
13771418
#[inline]
13781419
fn to_f32(&self) -> Option<f32> {
1379-
match self.data.len() {
1380-
0 => Some(f32::zero()),
1381-
1 => Some(self.data[0] as f32),
1382-
len => {
1383-
// this will prevent any overflow of exponent
1384-
if len > (f32::MAX_EXP as usize) / big_digit::BITS {
1385-
None
1386-
} else {
1387-
let exponent = (len - 2) * big_digit::BITS;
1388-
// we need 25 significant digits, 24 to be stored and 1 for rounding
1389-
// this gives at least 33 significant digits
1390-
let mantissa = big_digit::to_doublebigdigit(self.data[len - 1],
1391-
self.data[len - 2]);
1392-
// this cast handles rounding
1393-
let ret = (mantissa as f32) * 2.0.powi(exponent as i32);
1394-
if ret.is_infinite() {
1395-
None
1396-
} else {
1397-
Some(ret)
1398-
}
1399-
}
1420+
let mantissa = high_bits_to_u64(self);
1421+
let exponent = self.bits() - ilog2(mantissa);
1422+
1423+
if exponent > f32::MAX_EXP as usize {
1424+
None
1425+
} else {
1426+
let ret = (mantissa as f32) * 2.0f32.powi(exponent as i32);
1427+
if ret.is_infinite() {
1428+
None
1429+
} else {
1430+
Some(ret)
14001431
}
14011432
}
14021433
}
14031434

1404-
// `DoubleBigDigit` size dependent
14051435
#[inline]
14061436
fn to_f64(&self) -> Option<f64> {
1407-
match self.data.len() {
1408-
0 => Some(f64::zero()),
1409-
1 => Some(self.data[0] as f64),
1410-
2 => Some(big_digit::to_doublebigdigit(self.data[1], self.data[0]) as f64),
1411-
len => {
1412-
// this will prevent any overflow of exponent
1413-
if len > (f64::MAX_EXP as usize) / big_digit::BITS {
1414-
None
1415-
} else {
1416-
let mut exponent = (len - 2) * big_digit::BITS;
1417-
let mut mantissa = big_digit::to_doublebigdigit(self.data[len - 1],
1418-
self.data[len - 2]);
1419-
// we need at least 54 significant bit digits, 53 to be stored and 1 for rounding
1420-
// so we take enough from the next BigDigit to make it up to 64
1421-
let shift = mantissa.leading_zeros() as usize;
1422-
if shift > 0 {
1423-
mantissa <<= shift;
1424-
mantissa |= self.data[len - 3] as u64 >> (big_digit::BITS - shift);
1425-
exponent -= shift;
1426-
}
1427-
// this cast handles rounding
1428-
let ret = (mantissa as f64) * 2.0.powi(exponent as i32);
1429-
if ret.is_infinite() {
1430-
None
1431-
} else {
1432-
Some(ret)
1433-
}
1434-
}
1437+
let mantissa = high_bits_to_u64(self);
1438+
let exponent = self.bits() - ilog2(mantissa);
1439+
1440+
if exponent > f64::MAX_EXP as usize {
1441+
None
1442+
} else {
1443+
let ret = (mantissa as f64) * 2.0f64.powi(exponent as i32);
1444+
if ret.is_infinite() {
1445+
None
1446+
} else {
1447+
Some(ret)
14351448
}
14361449
}
14371450
}
@@ -1484,14 +1497,16 @@ impl FromPrimitive for BigUint {
14841497
}
14851498

14861499
impl From<u64> for BigUint {
1487-
// `DoubleBigDigit` size dependent
14881500
#[inline]
1489-
fn from(n: u64) -> Self {
1490-
match big_digit::from_doublebigdigit(n) {
1491-
(0, 0) => BigUint::zero(),
1492-
(0, n0) => BigUint { data: vec![n0] },
1493-
(n1, n0) => BigUint { data: vec![n0, n1] },
1501+
fn from(mut n: u64) -> Self {
1502+
let mut ret: BigUint = Zero::zero();
1503+
1504+
while n != 0 {
1505+
ret.data.push(n as BigDigit);
1506+
n = (n >> 1) >> (big_digit::BITS - 1);
14941507
}
1508+
1509+
ret
14951510
}
14961511
}
14971512

@@ -1591,28 +1606,35 @@ fn to_bitwise_digits_le(u: &BigUint, bits: usize) -> Vec<u8> {
15911606
fn to_inexact_bitwise_digits_le(u: &BigUint, bits: usize) -> Vec<u8> {
15921607
debug_assert!(!u.is_zero() && bits <= 8 && big_digit::BITS % bits != 0);
15931608

1594-
let last_i = u.data.len() - 1;
1595-
let mask: DoubleBigDigit = (1 << bits) - 1;
1609+
let mask: BigDigit = (1 << bits) - 1;
15961610
let digits = (u.bits() + bits - 1) / bits;
15971611
let mut res = Vec::with_capacity(digits);
15981612

15991613
let mut r = 0;
16001614
let mut rbits = 0;
1601-
for hi in u.data[..last_i].iter().cloned() {
1602-
r |= (hi as DoubleBigDigit) << rbits;
1615+
1616+
for c in &u.data[..] {
1617+
r |= *c << rbits;
16031618
rbits += big_digit::BITS;
16041619

16051620
while rbits >= bits {
16061621
res.push((r & mask) as u8);
16071622
r >>= bits;
1623+
1624+
if rbits > big_digit::BITS {
1625+
r = *c >> (big_digit::BITS - (rbits - bits));
1626+
}
1627+
16081628
rbits -= bits;
16091629
}
16101630
}
16111631

1612-
r |= (u.data[last_i] as DoubleBigDigit) << rbits;
1613-
while r != 0 {
1614-
res.push((r & mask) as u8);
1615-
r >>= bits;
1632+
if rbits != 0 {
1633+
res.push(r as u8);
1634+
}
1635+
1636+
while let Some(&0) = res.last() {
1637+
res.pop();
16161638
}
16171639

16181640
res
@@ -1629,8 +1651,7 @@ fn to_radix_digits_le(u: &BigUint, radix: u32) -> Vec<u8> {
16291651
let mut digits = u.clone();
16301652

16311653
let (base, power) = get_radix_base(radix);
1632-
debug_assert!(base < (1 << 32));
1633-
let base = base as BigDigit;
1654+
let radix = radix as BigDigit;
16341655

16351656
while digits.data.len() > 1 {
16361657
let (q, mut r) = div_rem_digit(digits, base);
@@ -1852,57 +1873,115 @@ impl serde::Deserialize for BigUint {
18521873
}
18531874
}
18541875

1855-
// `DoubleBigDigit` size dependent
18561876
/// Returns the greatest power of the radix <= big_digit::BASE
18571877
#[inline]
1858-
fn get_radix_base(radix: u32) -> (DoubleBigDigit, usize) {
1878+
fn get_radix_base(radix: u32) -> (BigDigit, usize) {
1879+
debug_assert!(2 <= radix && radix <= 36, "The radix must be within 2...36");
1880+
debug_assert!(!radix.is_power_of_two());
1881+
18591882
// To generate this table:
1860-
// let target = std::u32::max as u64 + 1;
18611883
// for radix in 2u64..37 {
1862-
// let power = (target as f64).log(radix as f64) as u32;
1863-
// let base = radix.pow(power);
1884+
// let mut power = big_digit::BITS / ilog2(radix as u64);
1885+
// let mut base = radix.pow(power as u32);
1886+
//
1887+
// while let Some(b) = base.checked_mul(radix) {
1888+
// if b > big_digit::MAX {
1889+
// break;
1890+
// }
1891+
// base = b;
1892+
// power += 1;
1893+
// }
1894+
//
18641895
// println!("({:10}, {:2}), // {:2}", base, power, radix);
18651896
// }
1866-
const BASES: [(DoubleBigDigit, usize); 37] = [(0, 0),
1867-
(0, 0),
1868-
(4294967296, 32), // 2
1869-
(3486784401, 20), // 3
1870-
(4294967296, 16), // 4
1871-
(1220703125, 13), // 5
1872-
(2176782336, 12), // 6
1873-
(1977326743, 11), // 7
1874-
(1073741824, 10), // 8
1875-
(3486784401, 10), // 9
1876-
(1000000000, 9), // 10
1877-
(2357947691, 9), // 11
1878-
(429981696, 8), // 12
1879-
(815730721, 8), // 13
1880-
(1475789056, 8), // 14
1881-
(2562890625, 8), // 15
1882-
(4294967296, 8), // 16
1883-
(410338673, 7), // 17
1884-
(612220032, 7), // 18
1885-
(893871739, 7), // 19
1886-
(1280000000, 7), // 20
1887-
(1801088541, 7), // 21
1888-
(2494357888, 7), // 22
1889-
(3404825447, 7), // 23
1890-
(191102976, 6), // 24
1891-
(244140625, 6), // 25
1892-
(308915776, 6), // 26
1893-
(387420489, 6), // 27
1894-
(481890304, 6), // 28
1895-
(594823321, 6), // 29
1896-
(729000000, 6), // 30
1897-
(887503681, 6), // 31
1898-
(1073741824, 6), // 32
1899-
(1291467969, 6), // 33
1900-
(1544804416, 6), // 34
1901-
(1838265625, 6), // 35
1902-
(2176782336, 6) /* 36 */];
19031897

1904-
assert!(2 <= radix && radix <= 36, "The radix must be within 2...36");
1905-
BASES[radix as usize]
1898+
match big_digit::BITS {
1899+
32 => {
1900+
const BASES: [(u32, usize); 37] = [(0, 0), (0, 0),
1901+
(0, 0), // 2
1902+
(3486784401, 20), // 3
1903+
(0, 0), // 4
1904+
(1220703125, 13), // 5
1905+
(2176782336, 12), // 6
1906+
(1977326743, 11), // 7
1907+
(0, 0), // 8
1908+
(3486784401, 10), // 9
1909+
(1000000000, 9), // 10
1910+
(2357947691, 9), // 11
1911+
(429981696, 8), // 12
1912+
(815730721, 8), // 13
1913+
(1475789056, 8), // 14
1914+
(2562890625, 8), // 15
1915+
(0, 0), // 16
1916+
(410338673, 7), // 17
1917+
(612220032, 7), // 18
1918+
(893871739, 7), // 19
1919+
(1280000000, 7), // 20
1920+
(1801088541, 7), // 21
1921+
(2494357888, 7), // 22
1922+
(3404825447, 7), // 23
1923+
(191102976, 6), // 24
1924+
(244140625, 6), // 25
1925+
(308915776, 6), // 26
1926+
(387420489, 6), // 27
1927+
(481890304, 6), // 28
1928+
(594823321, 6), // 29
1929+
(729000000, 6), // 30
1930+
(887503681, 6), // 31
1931+
(0, 0), // 32
1932+
(1291467969, 6), // 33
1933+
(1544804416, 6), // 34
1934+
(1838265625, 6), // 35
1935+
(2176782336, 6) /* 36 */
1936+
];
1937+
1938+
let (base, power) = BASES[radix as usize];
1939+
(base as BigDigit, power)
1940+
}
1941+
64 => {
1942+
const BASES: [(u64, usize); 37] = [(0, 0), (0, 0),
1943+
(9223372036854775808, 63), // 2
1944+
(12157665459056928801, 40), // 3
1945+
(4611686018427387904, 31), // 4
1946+
(7450580596923828125, 27), // 5
1947+
(4738381338321616896, 24), // 6
1948+
(3909821048582988049, 22), // 7
1949+
(9223372036854775808, 21), // 8
1950+
(12157665459056928801, 20), // 9
1951+
(10000000000000000000, 19), // 10
1952+
(5559917313492231481, 18), // 11
1953+
(2218611106740436992, 17), // 12
1954+
(8650415919381337933, 17), // 13
1955+
(2177953337809371136, 16), // 14
1956+
(6568408355712890625, 16), // 15
1957+
(1152921504606846976, 15), // 16
1958+
(2862423051509815793, 15), // 17
1959+
(6746640616477458432, 15), // 18
1960+
(15181127029874798299, 15), // 19
1961+
(1638400000000000000, 14), // 20
1962+
(3243919932521508681, 14), // 21
1963+
(6221821273427820544, 14), // 22
1964+
(11592836324538749809, 14), // 23
1965+
(876488338465357824, 13), // 24
1966+
(1490116119384765625, 13), // 25
1967+
(2481152873203736576, 13), // 26
1968+
(4052555153018976267, 13), // 27
1969+
(6502111422497947648, 13), // 28
1970+
(10260628712958602189, 13), // 29
1971+
(15943230000000000000, 13), // 30
1972+
(787662783788549761, 12), // 31
1973+
(1152921504606846976, 12), // 32
1974+
(1667889514952984961, 12), // 33
1975+
(2386420683693101056, 12), // 34
1976+
(3379220508056640625, 12), // 35
1977+
(4738381338321616896, 12), // 36
1978+
];
1979+
1980+
let (base, power) = BASES[radix as usize];
1981+
(base as BigDigit, power)
1982+
}
1983+
_ => panic!("Invalid bigdigit size")
1984+
}
19061985
}
19071986

19081987
/// A Sign is a `BigInt`'s composing element.
@@ -3454,13 +3533,12 @@ mod biguint_tests {
34543533
const N1: BigDigit = -1i32 as BigDigit;
34553534
const N2: BigDigit = -2i32 as BigDigit;
34563535

3457-
// `DoubleBigDigit` size dependent
34583536
#[test]
34593537
fn test_convert_i64() {
34603538
fn check(b1: BigUint, i: i64) {
34613539
let b2: BigUint = FromPrimitive::from_i64(i).unwrap();
3462-
assert!(b1 == b2);
3463-
assert!(b1.to_i64().unwrap() == i);
3540+
assert_eq!(b1, b2);
3541+
assert_eq!(b1.to_i64().unwrap(), i);
34643542
}
34653543

34663544
check(Zero::zero(), 0);
@@ -3469,23 +3547,20 @@ mod biguint_tests {
34693547

34703548
check(BigUint::new(vec![]), 0);
34713549
check(BigUint::new(vec![1]), (1 << (0 * big_digit::BITS)));
3472-
check(BigUint::new(vec![N1]), (1 << (1 * big_digit::BITS)) - 1);
3473-
check(BigUint::new(vec![0, 1]), (1 << (1 * big_digit::BITS)));
3474-
check(BigUint::new(vec![N1, N1 >> 1]), i64::MAX);
3550+
check((BigUint::one() << 63) - BigUint::one(), i64::MAX);
34753551

34763552
assert_eq!(i64::MIN.to_biguint(), None);
34773553
assert_eq!(BigUint::new(vec![N1, N1]).to_i64(), None);
34783554
assert_eq!(BigUint::new(vec![0, 0, 1]).to_i64(), None);
34793555
assert_eq!(BigUint::new(vec![N1, N1, N1]).to_i64(), None);
34803556
}
34813557

3482-
// `DoubleBigDigit` size dependent
34833558
#[test]
34843559
fn test_convert_u64() {
34853560
fn check(b1: BigUint, u: u64) {
34863561
let b2: BigUint = FromPrimitive::from_u64(u).unwrap();
3487-
assert!(b1 == b2);
3488-
assert!(b1.to_u64().unwrap() == u);
3562+
assert_eq!(b1, b2);
3563+
assert_eq!(b1.to_u64().unwrap(), u);
34893564
}
34903565

34913566
check(Zero::zero(), 0);
@@ -3495,9 +3570,7 @@ mod biguint_tests {
34953570

34963571
check(BigUint::new(vec![]), 0);
34973572
check(BigUint::new(vec![1]), (1 << (0 * big_digit::BITS)));
3498-
check(BigUint::new(vec![N1]), (1 << (1 * big_digit::BITS)) - 1);
3499-
check(BigUint::new(vec![0, 1]), (1 << (1 * big_digit::BITS)));
3500-
check(BigUint::new(vec![N1, N1]), u64::MAX);
3573+
check((BigUint::one() << 64) - BigUint::one(), u64::MAX);
35013574

35023575
assert_eq!(BigUint::new(vec![0, 0, 1]).to_u64(), None);
35033576
assert_eq!(BigUint::new(vec![N1, N1, N1]).to_u64(), None);
@@ -3515,7 +3588,7 @@ mod biguint_tests {
35153588
check(&BigUint::one(), 1.0);
35163589
check(&BigUint::from(u16::MAX), 2.0.powi(16) - 1.0);
35173590
check(&BigUint::from(1u64 << 32), 2.0.powi(32));
3518-
check(&BigUint::from_slice(&[0, 0, 1]), 2.0.powi(64));
3591+
check(&(BigUint::one() << 64), 2.0.powi(64));
35193592
check(&((BigUint::one() << 100) + (BigUint::one() << 123)),
35203593
2.0.powi(100) + 2.0.powi(123));
35213594
check(&(BigUint::one() << 127), 2.0.powi(127));
@@ -3586,7 +3659,7 @@ mod biguint_tests {
35863659
check(&BigUint::one(), 1.0);
35873660
check(&BigUint::from(u32::MAX), 2.0.powi(32) - 1.0);
35883661
check(&BigUint::from(1u64 << 32), 2.0.powi(32));
3589-
check(&BigUint::from_slice(&[0, 0, 1]), 2.0.powi(64));
3662+
check(&(BigUint::one() << 64), 2.0.powi(64));
35903663
check(&((BigUint::one() << 100) + (BigUint::one() << 152)),
35913664
2.0.powi(100) + 2.0.powi(152));
35923665
check(&(BigUint::one() << 1023), 2.0.powi(1023));
@@ -3664,8 +3737,8 @@ mod biguint_tests {
36643737

36653738
check!(u8, BigUint::from_slice(&[u8::MAX as BigDigit]));
36663739
check!(u16, BigUint::from_slice(&[u16::MAX as BigDigit]));
3667-
check!(u32, BigUint::from_slice(&[u32::MAX]));
3668-
check!(u64, BigUint::from_slice(&[u32::MAX, u32::MAX]));
3740+
check!(u32, BigUint::from_slice(&[u32::MAX as BigDigit]));
3741+
check!(u64, (BigUint::one() << 64) - BigUint::one());
36693742
check!(usize, BigUint::from(usize::MAX as u64));
36703743
}
36713744

@@ -3714,7 +3787,7 @@ mod biguint_tests {
37143787
a - b;
37153788
}
37163789

3717-
const M: u32 = ::std::u32::MAX;
3790+
const M: BigDigit = big_digit::MAX;
37183791
const MUL_TRIPLES: &'static [(&'static [BigDigit],
37193792
&'static [BigDigit],
37203793
&'static [BigDigit])] = &[(&[], &[], &[]),
@@ -3976,6 +4049,7 @@ mod biguint_tests {
39764049
format!("2{}1", repeat("0").take(bits / 2 - 1).collect::<String>())),
39774050
(10,
39784051
match bits {
4052+
64 => "36893488147419103233".to_string(),
39794053
32 => "8589934593".to_string(),
39804054
16 => "131073".to_string(),
39814055
_ => panic!(),
@@ -3993,12 +4067,14 @@ mod biguint_tests {
39934067
repeat("0").take(bits / 2 - 1).collect::<String>())),
39944068
(8,
39954069
match bits {
4070+
64 => "14000000000000000000004000000000000000000001".to_string(),
39964071
32 => "6000000000100000000001".to_string(),
39974072
16 => "140000400001".to_string(),
39984073
_ => panic!(),
39994074
}),
40004075
(10,
40014076
match bits {
4077+
64 => "1020847100762815390427017310442723737601".to_string(),
40024078
32 => "55340232229718589441".to_string(),
40034079
16 => "12885032961".to_string(),
40044080
_ => panic!(),
@@ -4481,7 +4557,7 @@ mod bigint_tests {
44814557
check(&BigInt::one(), 1.0);
44824558
check(&BigInt::from(u16::MAX), 2.0.powi(16) - 1.0);
44834559
check(&BigInt::from(1u64 << 32), 2.0.powi(32));
4484-
check(&BigInt::from_slice(Plus, &[0, 0, 1]), 2.0.powi(64));
4560+
check(&(BigInt::one() << 64), 2.0.powi(64));
44854561
check(&((BigInt::one() << 100) + (BigInt::one() << 123)),
44864562
2.0.powi(100) + 2.0.powi(123));
44874563
check(&(BigInt::one() << 127), 2.0.powi(127));
@@ -4563,7 +4639,7 @@ mod bigint_tests {
45634639
check(&BigInt::one(), 1.0);
45644640
check(&BigInt::from(u32::MAX), 2.0.powi(32) - 1.0);
45654641
check(&BigInt::from(1u64 << 32), 2.0.powi(32));
4566-
check(&BigInt::from_slice(Plus, &[0, 0, 1]), 2.0.powi(64));
4642+
check(&(BigInt::one() << 64), 2.0.powi(64));
45674643
check(&((BigInt::one() << 100) + (BigInt::one() << 152)),
45684644
2.0.powi(100) + 2.0.powi(152));
45694645
check(&(BigInt::one() << 1023), 2.0.powi(1023));
@@ -4652,8 +4728,7 @@ mod bigint_tests {
46524728
check!(u8, BigInt::from_slice(Plus, &[u8::MAX as BigDigit]));
46534729
check!(u16, BigInt::from_slice(Plus, &[u16::MAX as BigDigit]));
46544730
check!(u32, BigInt::from_slice(Plus, &[u32::MAX as BigDigit]));
4655-
check!(u64,
4656-
BigInt::from_slice(Plus, &[u32::MAX as BigDigit, u32::MAX as BigDigit]));
4731+
check!(u64, (BigInt::one() << 64) - BigInt::one());
46574732
check!(usize, BigInt::from(usize::MAX as u64));
46584733
}
46594734

@@ -4681,8 +4756,8 @@ mod bigint_tests {
46814756
BigInt::from_slice(Minus, &[1 << 31]),
46824757
BigInt::from_slice(Plus, &[i32::MAX as BigDigit]));
46834758
check!(i64,
4684-
BigInt::from_slice(Minus, &[0, 1 << 31]),
4685-
BigInt::from_slice(Plus, &[u32::MAX as BigDigit, i32::MAX as BigDigit]));
4759+
-((BigInt::one() << 63)),
4760+
(BigInt::one() << 63) - BigInt::one());
46864761
check!(isize,
46874762
BigInt::from(isize::MIN as i64),
46884763
BigInt::from(isize::MAX as i64));
@@ -4751,7 +4826,7 @@ mod bigint_tests {
47514826
}
47524827
}
47534828

4754-
const M: u32 = ::std::u32::MAX;
4829+
const M: BigDigit = big_digit::MAX;
47554830
static MUL_TRIPLES: &'static [(&'static [BigDigit],
47564831
&'static [BigDigit],
47574832
&'static [BigDigit])] = &[(&[], &[], &[]),

0 commit comments

Comments
 (0)
Please sign in to comment.