@@ -2,6 +2,51 @@ pub const SMALLEST_POWER_OF_FIVE: i32 = -342;
22pub const LARGEST_POWER_OF_FIVE : i32 = 308 ;
33pub const N_POWERS_OF_FIVE : usize = ( LARGEST_POWER_OF_FIVE - SMALLEST_POWER_OF_FIVE + 1 ) as usize ;
44
5+ #[ cfg( test) ]
6+ mod tests {
7+ use super :: * ;
8+
9+ use num_bigint:: BigUint ;
10+
11+ fn compute_pow5_128 ( q : i32 ) -> ( u64 , u64 ) {
12+ let mut c = if q < 0 {
13+ let pow5 = BigUint :: from ( 5_u8 ) . pow ( ( -q) as u32 ) ;
14+ let mut z = 0_u16 ;
15+ while ( BigUint :: from ( 1_u8 ) << z) < pow5 {
16+ z += 1 ;
17+ }
18+ let b = if q < -27 { 2 * z + 128 } else { z + 127 } ;
19+ ( BigUint :: from ( 1_u8 ) << b) / pow5 + BigUint :: from ( 1_u8 )
20+ } else {
21+ BigUint :: from ( 5_u8 ) . pow ( q as u32 )
22+ } ;
23+ while c < ( BigUint :: from ( 1_u8 ) << 127 ) {
24+ c <<= 1 ;
25+ }
26+ while c >= ( BigUint :: from ( 1_u8 ) << 128 ) {
27+ c >>= 1 ;
28+ }
29+ let mut digits = c. to_u32_digits ( ) ;
30+ while digits. len ( ) < 4 {
31+ digits. push ( 0 ) ;
32+ }
33+ assert_eq ! ( digits. len( ) , 4 ) ;
34+ let lo = ( digits[ 0 ] as u64 ) + ( digits[ 1 ] as u64 * ( 1_u64 << 32 ) ) ;
35+ let hi = ( digits[ 2 ] as u64 ) + ( digits[ 3 ] as u64 * ( 1_u64 << 32 ) ) ;
36+ ( hi, lo)
37+ }
38+
39+ #[ test]
40+ fn test_pow5_table ( ) {
41+ for q in SMALLEST_POWER_OF_FIVE ..=LARGEST_POWER_OF_FIVE {
42+ let ( hi, lo) = compute_pow5_128 ( q) ;
43+ let expected = POWER_OF_FIVE_128 [ ( q - SMALLEST_POWER_OF_FIVE ) as usize ] ;
44+ assert_eq ! ( hi, expected. 0 ) ;
45+ assert_eq ! ( lo, expected. 1 ) ;
46+ }
47+ }
48+ }
49+
550#[ allow( clippy:: unreadable_literal) ]
651pub const POWER_OF_FIVE_128 : [ ( u64 , u64 ) ; N_POWERS_OF_FIVE ] = [
752 ( 0xeef453d6923bd65a , 0x113faa2906a13b3f ) ,
0 commit comments