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