| 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 | |