lexical_parse_float/
table_decimal.rs

1//! Pre-computed tables for writing decimal strings.
2
3#![doc(hidden)]
4#![cfg(not(feature = "compact"))]
5
6#[cfg(not(feature = "radix"))]
7use crate::bigint::Limb;
8use crate::limits::{f32_exponent_limit, f64_exponent_limit, f64_mantissa_limit, u64_power_limit};
9#[cfg(not(feature = "power-of-two"))]
10use lexical_util::assert::debug_assert_radix;
11use static_assertions::const_assert;
12
13// HELPERS
14// -------
15
16/// Get lookup table for small int powers.
17///
18/// # Safety
19///
20/// Safe as long as the radix provided is valid, and exponent is smaller
21/// than the table for the radix.
22#[inline]
23#[cfg(not(feature = "power-of-two"))]
24pub unsafe fn get_small_int_power(exponent: usize, radix: u32) -> u64 {
25    // NOTE: don't check the radix since we also use it for half radix, or 5.
26    match radix {
27        5 => unsafe { get_small_int_power5(exponent) },
28        10 => unsafe { get_small_int_power10(exponent) },
29        _ => unreachable!(),
30    }
31}
32
33/// Get lookup table for small f32 powers.
34///
35/// # Safety
36///
37/// Safe as long as the radix provided is valid, and exponent is smaller
38/// than the table for the radix.
39#[inline]
40#[cfg(not(feature = "power-of-two"))]
41pub unsafe fn get_small_f32_power(exponent: usize, radix: u32) -> f32 {
42    debug_assert_radix(radix);
43    unsafe { get_small_f32_power10(exponent) }
44}
45
46/// Get lookup table for small f64 powers.
47///
48/// # Safety
49///
50/// Safe as long as the radix provided is valid, and exponent is smaller
51/// than the table for the radix.
52#[inline]
53#[cfg(not(feature = "power-of-two"))]
54pub unsafe fn get_small_f64_power(exponent: usize, radix: u32) -> f64 {
55    debug_assert_radix(radix);
56    unsafe { get_small_f64_power10(exponent) }
57}
58
59/// Get pre-computed power for a large power of radix.
60#[cfg(not(feature = "radix"))]
61pub const fn get_large_int_power(_: u32) -> (&'static [Limb], u32) {
62    (&LARGE_POW5, LARGE_POW5_STEP)
63}
64
65/// Get pre-computed int power of 5.
66///
67/// # Safety
68///
69/// Safe as long as the `exponent < SMALL_INT_POW5.len()`.
70#[inline(always)]
71pub unsafe fn get_small_int_power5(exponent: usize) -> u64 {
72    unsafe { index_unchecked!(SMALL_INT_POW5[exponent]) }
73}
74
75/// Get pre-computed int power of 10.
76///
77/// # Safety
78///
79/// Safe as long as the `exponent < SMALL_INT_POW10.len()`.
80#[inline(always)]
81pub unsafe fn get_small_int_power10(exponent: usize) -> u64 {
82    unsafe { index_unchecked!(SMALL_INT_POW10[exponent]) }
83}
84
85/// Get pre-computed f32 power of 10.
86///
87/// # Safety
88///
89/// Safe as long as the `exponent < SMALL_F32_POW10.len()`.
90#[inline(always)]
91pub unsafe fn get_small_f32_power10(exponent: usize) -> f32 {
92    unsafe { index_unchecked!(SMALL_F32_POW10[exponent]) }
93}
94
95/// Get pre-computed f64 power of 10.
96///
97/// # Safety
98///
99/// Safe as long as the `exponent < SMALL_F64_POW10.len()`.
100#[inline(always)]
101pub unsafe fn get_small_f64_power10(exponent: usize) -> f64 {
102    unsafe { index_unchecked!(SMALL_F64_POW10[exponent]) }
103}
104
105// TABLES
106// ------
107
108/// Pre-computed, small powers-of-5.
109pub const SMALL_INT_POW5: [u64; 28] = [
110    1,
111    5,
112    25,
113    125,
114    625,
115    3125,
116    15625,
117    78125,
118    390625,
119    1953125,
120    9765625,
121    48828125,
122    244140625,
123    1220703125,
124    6103515625,
125    30517578125,
126    152587890625,
127    762939453125,
128    3814697265625,
129    19073486328125,
130    95367431640625,
131    476837158203125,
132    2384185791015625,
133    11920928955078125,
134    59604644775390625,
135    298023223876953125,
136    1490116119384765625,
137    7450580596923828125,
138];
139const_assert!(SMALL_INT_POW5.len() > f64_mantissa_limit(5) as usize);
140const_assert!(SMALL_INT_POW5.len() == u64_power_limit(5) as usize + 1);
141
142/// Pre-computed, small powers-of-10.
143pub const SMALL_INT_POW10: [u64; 20] = [
144    1,
145    10,
146    100,
147    1000,
148    10000,
149    100000,
150    1000000,
151    10000000,
152    100000000,
153    1000000000,
154    10000000000,
155    100000000000,
156    1000000000000,
157    10000000000000,
158    100000000000000,
159    1000000000000000,
160    10000000000000000,
161    100000000000000000,
162    1000000000000000000,
163    10000000000000000000,
164];
165const_assert!(SMALL_INT_POW10.len() > f64_mantissa_limit(10) as usize);
166const_assert!(SMALL_INT_POW10.len() == u64_power_limit(10) as usize + 1);
167
168/// Pre-computed, small powers-of-10.
169pub const SMALL_F32_POW10: [f32; 16] =
170    [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 0., 0., 0., 0., 0.];
171const_assert!(SMALL_F32_POW10.len() > f32_exponent_limit(10).1 as usize);
172
173/// Pre-computed, small powers-of-10.
174pub const SMALL_F64_POW10: [f64; 32] = [
175    1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16,
176    1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 0., 0., 0., 0., 0., 0., 0., 0., 0.,
177];
178const_assert!(SMALL_F64_POW10.len() > f64_exponent_limit(10).1 as usize);
179
180/// Pre-computed large power-of-5 for 32-bit limbs.
181#[cfg(not(all(target_pointer_width = "64", not(target_arch = "sparc"))))]
182pub const LARGE_POW5: [u32; 10] = [
183    4279965485, 329373468, 4020270615, 2137533757, 4287402176, 1057042919, 1071430142, 2440757623,
184    381945767, 46164893,
185];
186
187/// Pre-computed large power-of-5 for 64-bit limbs.
188#[cfg(all(target_pointer_width = "64", not(target_arch = "sparc")))]
189pub const LARGE_POW5: [u64; 5] = [
190    1414648277510068013,
191    9180637584431281687,
192    4539964771860779200,
193    10482974169319127550,
194    198276706040285095,
195];
196
197/// Step for large power-of-5 for 32-bit limbs.
198pub const LARGE_POW5_STEP: u32 = 135;