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 ] |
22 | 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 ] |
29 | 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 ] |
54 | pub fn get_small(&self, index: usize) -> ExtendedFloat { |
55 | self.small.get_extended_float(index) |
56 | } |
57 | |
58 | #[inline ] |
59 | pub fn get_large(&self, index: usize) -> ExtendedFloat { |
60 | self.large.get_extended_float(index) |
61 | } |
62 | |
63 | #[inline ] |
64 | 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. |
74 | fn get_powers() -> &'static ModeratePathPowers; |
75 | } |
76 | |
77 | impl ModeratePathCache for ExtendedFloat { |
78 | #[inline ] |
79 | fn get_powers() -> &'static ModeratePathPowers { |
80 | cached_float80::get_powers() |
81 | } |
82 | } |
83 | |