@@ -127,6 +127,7 @@ pub mod big_digit {
127
127
128
128
// `DoubleBigDigit` size dependent
129
129
pub const BITS : usize = 32 ;
130
+ pub use :: std:: u32:: MAX ;
130
131
131
132
pub const BASE : DoubleBigDigit = 1 << BITS ;
132
133
const LO_MASK : DoubleBigDigit = ( -1i32 as DoubleBigDigit ) >> BITS ;
@@ -306,7 +307,8 @@ impl FromStr for BigUint {
306
307
}
307
308
}
308
309
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
310
312
fn from_bitwise_digits_le ( v : & [ u8 ] , bits : usize ) -> BigUint {
311
313
debug_assert ! ( !v. is_empty( ) && bits <= 8 && big_digit:: BITS % bits == 0 ) ;
312
314
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 {
315
317
316
318
let data = v. chunks ( digits_per_big_digit)
317
319
. 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 )
319
321
} )
320
322
. collect ( ) ;
321
323
322
324
BigUint :: new ( data)
323
325
}
324
326
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
326
329
fn from_inexact_bitwise_digits_le ( v : & [ u8 ] , bits : usize ) -> BigUint {
327
330
debug_assert ! ( !v. is_empty( ) && bits <= 8 && big_digit:: BITS % bits != 0 ) ;
328
331
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 {
333
336
let mut d = 0 ;
334
337
let mut dbits = 0 ;
335
338
for & c in v {
336
- d |= ( c as DoubleBigDigit ) << dbits;
339
+ d |= ( c as BigDigit ) << dbits;
337
340
dbits += bits;
341
+
338
342
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) ;
342
344
dbits -= big_digit:: BITS ;
345
+ d = ( c as BigDigit ) >> ( bits - dbits) ;
343
346
}
344
347
}
345
348
@@ -362,8 +365,7 @@ fn from_radix_digits_be(v: &[u8], radix: u32) -> BigUint {
362
365
let mut data = Vec :: with_capacity ( big_digits as usize ) ;
363
366
364
367
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 ;
367
369
368
370
let r = v. len ( ) % power;
369
371
let i = if r == 0 {
@@ -1349,6 +1351,40 @@ impl Integer for BigUint {
1349
1351
}
1350
1352
}
1351
1353
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
+
1352
1388
impl ToPrimitive for BigUint {
1353
1389
#[ inline]
1354
1390
fn to_i64 ( & self ) -> Option < i64 > {
@@ -1362,76 +1398,53 @@ impl ToPrimitive for BigUint {
1362
1398
} )
1363
1399
}
1364
1400
1365
- // `DoubleBigDigit` size dependent
1366
1401
#[ inline]
1367
1402
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 ;
1373
1413
}
1414
+
1415
+ Some ( ret)
1374
1416
}
1375
1417
1376
- // `DoubleBigDigit` size dependent
1377
1418
#[ inline]
1378
1419
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)
1400
1431
}
1401
1432
}
1402
1433
}
1403
1434
1404
- // `DoubleBigDigit` size dependent
1405
1435
#[ inline]
1406
1436
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)
1435
1448
}
1436
1449
}
1437
1450
}
@@ -1484,14 +1497,16 @@ impl FromPrimitive for BigUint {
1484
1497
}
1485
1498
1486
1499
impl From < u64 > for BigUint {
1487
- // `DoubleBigDigit` size dependent
1488
1500
#[ 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 ) ;
1494
1507
}
1508
+
1509
+ ret
1495
1510
}
1496
1511
}
1497
1512
@@ -1591,28 +1606,35 @@ fn to_bitwise_digits_le(u: &BigUint, bits: usize) -> Vec<u8> {
1591
1606
fn to_inexact_bitwise_digits_le ( u : & BigUint , bits : usize ) -> Vec < u8 > {
1592
1607
debug_assert ! ( !u. is_zero( ) && bits <= 8 && big_digit:: BITS % bits != 0 ) ;
1593
1608
1594
- let last_i = u. data . len ( ) - 1 ;
1595
- let mask: DoubleBigDigit = ( 1 << bits) - 1 ;
1609
+ let mask: BigDigit = ( 1 << bits) - 1 ;
1596
1610
let digits = ( u. bits ( ) + bits - 1 ) / bits;
1597
1611
let mut res = Vec :: with_capacity ( digits) ;
1598
1612
1599
1613
let mut r = 0 ;
1600
1614
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;
1603
1618
rbits += big_digit:: BITS ;
1604
1619
1605
1620
while rbits >= bits {
1606
1621
res. push ( ( r & mask) as u8 ) ;
1607
1622
r >>= bits;
1623
+
1624
+ if rbits > big_digit:: BITS {
1625
+ r = * c >> ( big_digit:: BITS - ( rbits - bits) ) ;
1626
+ }
1627
+
1608
1628
rbits -= bits;
1609
1629
}
1610
1630
}
1611
1631
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 ( ) ;
1616
1638
}
1617
1639
1618
1640
res
@@ -1629,8 +1651,7 @@ fn to_radix_digits_le(u: &BigUint, radix: u32) -> Vec<u8> {
1629
1651
let mut digits = u. clone ( ) ;
1630
1652
1631
1653
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 ;
1634
1655
1635
1656
while digits. data . len ( ) > 1 {
1636
1657
let ( q, mut r) = div_rem_digit ( digits, base) ;
@@ -1852,57 +1873,115 @@ impl serde::Deserialize for BigUint {
1852
1873
}
1853
1874
}
1854
1875
1855
- // `DoubleBigDigit` size dependent
1856
1876
/// Returns the greatest power of the radix <= big_digit::BASE
1857
1877
#[ 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
+
1859
1882
// To generate this table:
1860
- // let target = std::u32::max as u64 + 1;
1861
1883
// 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
+ //
1864
1895
// println!("({:10}, {:2}), // {:2}", base, power, radix);
1865
1896
// }
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 */ ] ;
1903
1897
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
+ }
1906
1985
}
1907
1986
1908
1987
/// A Sign is a `BigInt`'s composing element.
@@ -3454,13 +3533,12 @@ mod biguint_tests {
3454
3533
const N1 : BigDigit = -1i32 as BigDigit ;
3455
3534
const N2 : BigDigit = -2i32 as BigDigit ;
3456
3535
3457
- // `DoubleBigDigit` size dependent
3458
3536
#[ test]
3459
3537
fn test_convert_i64 ( ) {
3460
3538
fn check ( b1 : BigUint , i : i64 ) {
3461
3539
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) ;
3464
3542
}
3465
3543
3466
3544
check ( Zero :: zero ( ) , 0 ) ;
@@ -3469,23 +3547,20 @@ mod biguint_tests {
3469
3547
3470
3548
check ( BigUint :: new ( vec ! [ ] ) , 0 ) ;
3471
3549
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 ) ;
3475
3551
3476
3552
assert_eq ! ( i64 :: MIN . to_biguint( ) , None ) ;
3477
3553
assert_eq ! ( BigUint :: new( vec![ N1 , N1 ] ) . to_i64( ) , None ) ;
3478
3554
assert_eq ! ( BigUint :: new( vec![ 0 , 0 , 1 ] ) . to_i64( ) , None ) ;
3479
3555
assert_eq ! ( BigUint :: new( vec![ N1 , N1 , N1 ] ) . to_i64( ) , None ) ;
3480
3556
}
3481
3557
3482
- // `DoubleBigDigit` size dependent
3483
3558
#[ test]
3484
3559
fn test_convert_u64 ( ) {
3485
3560
fn check ( b1 : BigUint , u : u64 ) {
3486
3561
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) ;
3489
3564
}
3490
3565
3491
3566
check ( Zero :: zero ( ) , 0 ) ;
@@ -3495,9 +3570,7 @@ mod biguint_tests {
3495
3570
3496
3571
check ( BigUint :: new ( vec ! [ ] ) , 0 ) ;
3497
3572
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 ) ;
3501
3574
3502
3575
assert_eq ! ( BigUint :: new( vec![ 0 , 0 , 1 ] ) . to_u64( ) , None ) ;
3503
3576
assert_eq ! ( BigUint :: new( vec![ N1 , N1 , N1 ] ) . to_u64( ) , None ) ;
@@ -3515,7 +3588,7 @@ mod biguint_tests {
3515
3588
check ( & BigUint :: one ( ) , 1.0 ) ;
3516
3589
check ( & BigUint :: from ( u16:: MAX ) , 2.0 . powi ( 16 ) - 1.0 ) ;
3517
3590
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 ) ) ;
3519
3592
check ( & ( ( BigUint :: one ( ) << 100 ) + ( BigUint :: one ( ) << 123 ) ) ,
3520
3593
2.0 . powi ( 100 ) + 2.0 . powi ( 123 ) ) ;
3521
3594
check ( & ( BigUint :: one ( ) << 127 ) , 2.0 . powi ( 127 ) ) ;
@@ -3586,7 +3659,7 @@ mod biguint_tests {
3586
3659
check ( & BigUint :: one ( ) , 1.0 ) ;
3587
3660
check ( & BigUint :: from ( u32:: MAX ) , 2.0 . powi ( 32 ) - 1.0 ) ;
3588
3661
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 ) ) ;
3590
3663
check ( & ( ( BigUint :: one ( ) << 100 ) + ( BigUint :: one ( ) << 152 ) ) ,
3591
3664
2.0 . powi ( 100 ) + 2.0 . powi ( 152 ) ) ;
3592
3665
check ( & ( BigUint :: one ( ) << 1023 ) , 2.0 . powi ( 1023 ) ) ;
@@ -3664,8 +3737,8 @@ mod biguint_tests {
3664
3737
3665
3738
check ! ( u8 , BigUint :: from_slice( & [ u8 :: MAX as BigDigit ] ) ) ;
3666
3739
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 ( ) ) ;
3669
3742
check ! ( usize , BigUint :: from( usize :: MAX as u64 ) ) ;
3670
3743
}
3671
3744
@@ -3714,7 +3787,7 @@ mod biguint_tests {
3714
3787
a - b;
3715
3788
}
3716
3789
3717
- const M : u32 = :: std :: u32 :: MAX ;
3790
+ const M : BigDigit = big_digit :: MAX ;
3718
3791
const MUL_TRIPLES : & ' static [ ( & ' static [ BigDigit ] ,
3719
3792
& ' static [ BigDigit ] ,
3720
3793
& ' static [ BigDigit ] ) ] = & [ ( & [ ] , & [ ] , & [ ] ) ,
@@ -3976,6 +4049,7 @@ mod biguint_tests {
3976
4049
format!( "2{}1" , repeat( "0" ) . take( bits / 2 - 1 ) . collect:: <String >( ) ) ) ,
3977
4050
( 10 ,
3978
4051
match bits {
4052
+ 64 => "36893488147419103233" . to_string( ) ,
3979
4053
32 => "8589934593" . to_string( ) ,
3980
4054
16 => "131073" . to_string( ) ,
3981
4055
_ => panic!( ) ,
@@ -3993,12 +4067,14 @@ mod biguint_tests {
3993
4067
repeat( "0" ) . take( bits / 2 - 1 ) . collect:: <String >( ) ) ) ,
3994
4068
( 8 ,
3995
4069
match bits {
4070
+ 64 => "14000000000000000000004000000000000000000001" . to_string( ) ,
3996
4071
32 => "6000000000100000000001" . to_string( ) ,
3997
4072
16 => "140000400001" . to_string( ) ,
3998
4073
_ => panic!( ) ,
3999
4074
} ) ,
4000
4075
( 10 ,
4001
4076
match bits {
4077
+ 64 => "1020847100762815390427017310442723737601" . to_string( ) ,
4002
4078
32 => "55340232229718589441" . to_string( ) ,
4003
4079
16 => "12885032961" . to_string( ) ,
4004
4080
_ => panic!( ) ,
@@ -4481,7 +4557,7 @@ mod bigint_tests {
4481
4557
check ( & BigInt :: one ( ) , 1.0 ) ;
4482
4558
check ( & BigInt :: from ( u16:: MAX ) , 2.0 . powi ( 16 ) - 1.0 ) ;
4483
4559
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 ) ) ;
4485
4561
check ( & ( ( BigInt :: one ( ) << 100 ) + ( BigInt :: one ( ) << 123 ) ) ,
4486
4562
2.0 . powi ( 100 ) + 2.0 . powi ( 123 ) ) ;
4487
4563
check ( & ( BigInt :: one ( ) << 127 ) , 2.0 . powi ( 127 ) ) ;
@@ -4563,7 +4639,7 @@ mod bigint_tests {
4563
4639
check ( & BigInt :: one ( ) , 1.0 ) ;
4564
4640
check ( & BigInt :: from ( u32:: MAX ) , 2.0 . powi ( 32 ) - 1.0 ) ;
4565
4641
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 ) ) ;
4567
4643
check ( & ( ( BigInt :: one ( ) << 100 ) + ( BigInt :: one ( ) << 152 ) ) ,
4568
4644
2.0 . powi ( 100 ) + 2.0 . powi ( 152 ) ) ;
4569
4645
check ( & ( BigInt :: one ( ) << 1023 ) , 2.0 . powi ( 1023 ) ) ;
@@ -4652,8 +4728,7 @@ mod bigint_tests {
4652
4728
check ! ( u8 , BigInt :: from_slice( Plus , & [ u8 :: MAX as BigDigit ] ) ) ;
4653
4729
check ! ( u16 , BigInt :: from_slice( Plus , & [ u16 :: MAX as BigDigit ] ) ) ;
4654
4730
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( ) ) ;
4657
4732
check ! ( usize , BigInt :: from( usize :: MAX as u64 ) ) ;
4658
4733
}
4659
4734
@@ -4681,8 +4756,8 @@ mod bigint_tests {
4681
4756
BigInt :: from_slice( Minus , & [ 1 << 31 ] ) ,
4682
4757
BigInt :: from_slice( Plus , & [ i32 :: MAX as BigDigit ] ) ) ;
4683
4758
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 ( ) ) ;
4686
4761
check ! ( isize ,
4687
4762
BigInt :: from( isize :: MIN as i64 ) ,
4688
4763
BigInt :: from( isize :: MAX as i64 ) ) ;
@@ -4751,7 +4826,7 @@ mod bigint_tests {
4751
4826
}
4752
4827
}
4753
4828
4754
- const M : u32 = :: std :: u32 :: MAX ;
4829
+ const M : BigDigit = big_digit :: MAX ;
4755
4830
static MUL_TRIPLES : & ' static [ ( & ' static [ BigDigit ] ,
4756
4831
& ' static [ BigDigit ] ,
4757
4832
& ' static [ BigDigit ] ) ] = & [ ( & [ ] , & [ ] , & [ ] ) ,
0 commit comments