1// Adapted from https://github.com/Alexhuszagh/rust-lexical.
2
3//! Cached powers trait for extended-precision floats.
4
5use super::cached_float80;
6use super::float::ExtendedFloat;
7
8// POWERS
9
10/// Precalculated powers that uses two-separate arrays for memory-efficiency.
11#[doc(hidden)]
12pub(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
20impl 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)]
38pub(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
52impl 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.
72pub(crate) trait ModeratePathCache {
73 /// Get cached powers.
74 fn get_powers() -> &'static ModeratePathPowers;
75}
76
77impl ModeratePathCache for ExtendedFloat {
78 #[inline]
79 fn get_powers() -> &'static ModeratePathPowers {
80 cached_float80::get_powers()
81 }
82}
83