serde_json/lexical/
cached.rs

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}