1 // Adapted from https://github.com/Alexhuszagh/rust-lexical.
2 
3 //! Cached powers trait for extended-precision floats.
4 
5 use super::cached_float80;
6 use super::float::ExtendedFloat;
7 
8 // POWERS
9 
10 /// Precalculated powers that uses two-separate arrays for memory-efficiency.
11 #[doc(hidden)]
12 pub(crate) struct ExtendedFloatArray {
13     // Pre-calculated mantissa for the powers.
14     pub mant: &'static [u64],
15     // Pre-calculated binary exponents for the powers.
16     pub exp: &'static [i32],
17 }
18 
19 /// Allow indexing of values without bounds checking
20 impl ExtendedFloatArray {
21     #[inline]
get_extended_float(&self, index: usize) -> ExtendedFloat22     pub fn get_extended_float(&self, index: usize) -> ExtendedFloat {
23         let mant = self.mant[index];
24         let exp = self.exp[index];
25         ExtendedFloat { mant, exp }
26     }
27 
28     #[inline]
len(&self) -> usize29     pub fn len(&self) -> usize {
30         self.mant.len()
31     }
32 }
33 
34 // MODERATE PATH POWERS
35 
36 /// Precalculated powers of base N for the moderate path.
37 #[doc(hidden)]
38 pub(crate) struct ModeratePathPowers {
39     // Pre-calculated small powers.
40     pub small: ExtendedFloatArray,
41     // Pre-calculated large powers.
42     pub large: ExtendedFloatArray,
43     /// Pre-calculated small powers as 64-bit integers
44     pub small_int: &'static [u64],
45     // Step between large powers and number of small powers.
46     pub step: i32,
47     // Exponent bias for the large powers.
48     pub bias: i32,
49 }
50 
51 /// Allow indexing of values without bounds checking
52 impl ModeratePathPowers {
53     #[inline]
get_small(&self, index: usize) -> ExtendedFloat54     pub fn get_small(&self, index: usize) -> ExtendedFloat {
55         self.small.get_extended_float(index)
56     }
57 
58     #[inline]
get_large(&self, index: usize) -> ExtendedFloat59     pub fn get_large(&self, index: usize) -> ExtendedFloat {
60         self.large.get_extended_float(index)
61     }
62 
63     #[inline]
get_small_int(&self, index: usize) -> u6464     pub fn get_small_int(&self, index: usize) -> u64 {
65         self.small_int[index]
66     }
67 }
68 
69 // CACHED EXTENDED POWERS
70 
71 /// Cached powers as a trait for a floating-point type.
72 pub(crate) trait ModeratePathCache {
73     /// Get cached powers.
get_powers() -> &'static ModeratePathPowers74     fn get_powers() -> &'static ModeratePathPowers;
75 }
76 
77 impl ModeratePathCache for ExtendedFloat {
78     #[inline]
get_powers() -> &'static ModeratePathPowers79     fn get_powers() -> &'static ModeratePathPowers {
80         cached_float80::get_powers()
81     }
82 }
83