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