@@ -2,6 +2,51 @@ pub const SMALLEST_POWER_OF_FIVE: i32 = -342;
2
2
pub const LARGEST_POWER_OF_FIVE : i32 = 308 ;
3
3
pub const N_POWERS_OF_FIVE : usize = ( LARGEST_POWER_OF_FIVE - SMALLEST_POWER_OF_FIVE + 1 ) as usize ;
4
4
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
+
5
50
#[ allow( clippy:: unreadable_literal) ]
6
51
pub const POWER_OF_FIVE_128 : [ ( u64 , u64 ) ; N_POWERS_OF_FIVE ] = [
7
52
( 0xeef453d6923bd65a , 0x113faa2906a13b3f ) ,
0 commit comments