| // Adapted from https://github.com/Alexhuszagh/rust-lexical. |
| |
| //! Cached powers trait for extended-precision floats. |
| |
| use super::cached_float80; |
| use super::float::ExtendedFloat; |
| |
| // POWERS |
| |
| /// Precalculated powers that uses two-separate arrays for memory-efficiency. |
| #[doc(hidden)] |
| pub(crate) struct ExtendedFloatArray { |
| // Pre-calculated mantissa for the powers. |
| pub mant: &'static [u64], |
| // Pre-calculated binary exponents for the powers. |
| pub exp: &'static [i32], |
| } |
| |
| /// Allow indexing of values without bounds checking |
| impl ExtendedFloatArray { |
| #[inline] |
| pub fn get_extended_float(&self, index: usize) -> ExtendedFloat { |
| let mant = self.mant[index]; |
| let exp = self.exp[index]; |
| ExtendedFloat { mant, exp } |
| } |
| |
| #[inline] |
| pub fn len(&self) -> usize { |
| self.mant.len() |
| } |
| } |
| |
| // MODERATE PATH POWERS |
| |
| /// Precalculated powers of base N for the moderate path. |
| #[doc(hidden)] |
| pub(crate) struct ModeratePathPowers { |
| // Pre-calculated small powers. |
| pub small: ExtendedFloatArray, |
| // Pre-calculated large powers. |
| pub large: ExtendedFloatArray, |
| /// Pre-calculated small powers as 64-bit integers |
| pub small_int: &'static [u64], |
| // Step between large powers and number of small powers. |
| pub step: i32, |
| // Exponent bias for the large powers. |
| pub bias: i32, |
| } |
| |
| /// Allow indexing of values without bounds checking |
| impl ModeratePathPowers { |
| #[inline] |
| pub fn get_small(&self, index: usize) -> ExtendedFloat { |
| self.small.get_extended_float(index) |
| } |
| |
| #[inline] |
| pub fn get_large(&self, index: usize) -> ExtendedFloat { |
| self.large.get_extended_float(index) |
| } |
| |
| #[inline] |
| pub fn get_small_int(&self, index: usize) -> u64 { |
| self.small_int[index] |
| } |
| } |
| |
| // CACHED EXTENDED POWERS |
| |
| /// Cached powers as a trait for a floating-point type. |
| pub(crate) trait ModeratePathCache { |
| /// Get cached powers. |
| fn get_powers() -> &'static ModeratePathPowers; |
| } |
| |
| impl ModeratePathCache for ExtendedFloat { |
| #[inline] |
| fn get_powers() -> &'static ModeratePathPowers { |
| cached_float80::get_powers() |
| } |
| } |