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 perftools_inline!{ 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 perftools_inline!{ 32 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 perftools_inline!{ 57 pub fn get_small(&self, index: usize) -> ExtendedFloat<M> { 58 self.small.get_extended_float(index) 59 }} 60 61 perftools_inline!{ 62 pub fn get_large(&self, index: usize) -> ExtendedFloat<M> { 63 self.large.get_extended_float(index) 64 }} 65 66 perftools_inline!{ 67 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 perftools_inline!{ 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 perftools_inline!{ 90 fn get_powers(radix: u32) -> &'static ModeratePathPowers<u128> { 91 cached_float160::get_powers(radix) 92 }} 93 } 94