serde_json/lexical/
num.rs

1// Adapted from https://github.com/Alexhuszagh/rust-lexical.
2
3//! Utilities for Rust numbers.
4
5use core::ops;
6
7/// Precalculated values of radix**i for i in range [0, arr.len()-1].
8/// Each value can be **exactly** represented as that type.
9const F32_POW10: [f32; 11] = [
10    1.0,
11    10.0,
12    100.0,
13    1000.0,
14    10000.0,
15    100000.0,
16    1000000.0,
17    10000000.0,
18    100000000.0,
19    1000000000.0,
20    10000000000.0,
21];
22
23/// Precalculated values of radix**i for i in range [0, arr.len()-1].
24/// Each value can be **exactly** represented as that type.
25const F64_POW10: [f64; 23] = [
26    1.0,
27    10.0,
28    100.0,
29    1000.0,
30    10000.0,
31    100000.0,
32    1000000.0,
33    10000000.0,
34    100000000.0,
35    1000000000.0,
36    10000000000.0,
37    100000000000.0,
38    1000000000000.0,
39    10000000000000.0,
40    100000000000000.0,
41    1000000000000000.0,
42    10000000000000000.0,
43    100000000000000000.0,
44    1000000000000000000.0,
45    10000000000000000000.0,
46    100000000000000000000.0,
47    1000000000000000000000.0,
48    10000000000000000000000.0,
49];
50
51/// Type that can be converted to primitive with `as`.
52pub trait AsPrimitive: Sized + Copy + PartialOrd {
53    fn as_u32(self) -> u32;
54    fn as_u64(self) -> u64;
55    fn as_u128(self) -> u128;
56    fn as_usize(self) -> usize;
57    fn as_f32(self) -> f32;
58    fn as_f64(self) -> f64;
59}
60
61macro_rules! as_primitive_impl {
62    ($($ty:ident)*) => {
63        $(
64            impl AsPrimitive for $ty {
65                #[inline]
66                fn as_u32(self) -> u32 {
67                    self as u32
68                }
69
70                #[inline]
71                fn as_u64(self) -> u64 {
72                    self as u64
73                }
74
75                #[inline]
76                fn as_u128(self) -> u128 {
77                    self as u128
78                }
79
80                #[inline]
81                fn as_usize(self) -> usize {
82                    self as usize
83                }
84
85                #[inline]
86                fn as_f32(self) -> f32 {
87                    self as f32
88                }
89
90                #[inline]
91                fn as_f64(self) -> f64 {
92                    self as f64
93                }
94            }
95        )*
96    };
97}
98
99as_primitive_impl! { u32 u64 u128 usize f32 f64 }
100
101/// An interface for casting between machine scalars.
102pub trait AsCast: AsPrimitive {
103    /// Creates a number from another value that can be converted into
104    /// a primitive via the `AsPrimitive` trait.
105    fn as_cast<N: AsPrimitive>(n: N) -> Self;
106}
107
108macro_rules! as_cast_impl {
109    ($ty:ident, $method:ident) => {
110        impl AsCast for $ty {
111            #[inline]
112            fn as_cast<N: AsPrimitive>(n: N) -> Self {
113                n.$method()
114            }
115        }
116    };
117}
118
119as_cast_impl!(u32, as_u32);
120as_cast_impl!(u64, as_u64);
121as_cast_impl!(u128, as_u128);
122as_cast_impl!(usize, as_usize);
123as_cast_impl!(f32, as_f32);
124as_cast_impl!(f64, as_f64);
125
126/// Numerical type trait.
127pub trait Number: AsCast + ops::Add<Output = Self> {}
128
129macro_rules! number_impl {
130    ($($ty:ident)*) => {
131        $(
132            impl Number for $ty {}
133        )*
134    };
135}
136
137number_impl! { u32 u64 u128 usize f32 f64 }
138
139/// Defines a trait that supports integral operations.
140pub trait Integer: Number + ops::BitAnd<Output = Self> + ops::Shr<i32, Output = Self> {
141    const ZERO: Self;
142}
143
144macro_rules! integer_impl {
145    ($($ty:tt)*) => {
146        $(
147            impl Integer for $ty {
148                const ZERO: Self = 0;
149            }
150        )*
151    };
152}
153
154integer_impl! { u32 u64 u128 usize }
155
156/// Type trait for the mantissa type.
157pub trait Mantissa: Integer {
158    /// Mask to extract the high bits from the integer.
159    const HIMASK: Self;
160    /// Mask to extract the low bits from the integer.
161    const LOMASK: Self;
162    /// Full size of the integer, in bits.
163    const FULL: i32;
164    /// Half size of the integer, in bits.
165    const HALF: i32 = Self::FULL / 2;
166}
167
168impl Mantissa for u64 {
169    const HIMASK: u64 = 0xFFFFFFFF00000000;
170    const LOMASK: u64 = 0x00000000FFFFFFFF;
171    const FULL: i32 = 64;
172}
173
174/// Get exact exponent limit for radix.
175pub trait Float: Number {
176    /// Unsigned type of the same size.
177    type Unsigned: Integer;
178
179    /// Literal zero.
180    const ZERO: Self;
181    /// Maximum number of digits that can contribute in the mantissa.
182    ///
183    /// We can exactly represent a float in radix `b` from radix 2 if
184    /// `b` is divisible by 2. This function calculates the exact number of
185    /// digits required to exactly represent that float.
186    ///
187    /// According to the "Handbook of Floating Point Arithmetic",
188    /// for IEEE754, with emin being the min exponent, p2 being the
189    /// precision, and b being the radix, the number of digits follows as:
190    ///
191    /// `−emin + p2 + ⌊(emin + 1) log(2, b) − log(1 − 2^(−p2), b)⌋`
192    ///
193    /// For f32, this follows as:
194    ///     emin = -126
195    ///     p2 = 24
196    ///
197    /// For f64, this follows as:
198    ///     emin = -1022
199    ///     p2 = 53
200    ///
201    /// In Python:
202    ///     `-emin + p2 + math.floor((emin+1)*math.log(2, b) - math.log(1-2**(-p2), b))`
203    ///
204    /// This was used to calculate the maximum number of digits for [2, 36].
205    const MAX_DIGITS: usize;
206
207    // MASKS
208
209    /// Bitmask for the exponent, including the hidden bit.
210    const EXPONENT_MASK: Self::Unsigned;
211    /// Bitmask for the hidden bit in exponent, which is an implicit 1 in the fraction.
212    const HIDDEN_BIT_MASK: Self::Unsigned;
213    /// Bitmask for the mantissa (fraction), excluding the hidden bit.
214    const MANTISSA_MASK: Self::Unsigned;
215
216    // PROPERTIES
217
218    /// Positive infinity as bits.
219    const INFINITY_BITS: Self::Unsigned;
220    /// Size of the significand (mantissa) without hidden bit.
221    const MANTISSA_SIZE: i32;
222    /// Bias of the exponent
223    const EXPONENT_BIAS: i32;
224    /// Exponent portion of a denormal float.
225    const DENORMAL_EXPONENT: i32;
226    /// Maximum exponent value in float.
227    const MAX_EXPONENT: i32;
228
229    // ROUNDING
230
231    /// Default number of bits to shift (or 64 - mantissa size - 1).
232    const DEFAULT_SHIFT: i32;
233    /// Mask to determine if a full-carry occurred (1 in bit above hidden bit).
234    const CARRY_MASK: u64;
235
236    /// Get min and max exponent limits (exact) from radix.
237    fn exponent_limit() -> (i32, i32);
238
239    /// Get the number of digits that can be shifted from exponent to mantissa.
240    fn mantissa_limit() -> i32;
241
242    // Re-exported methods from std.
243    fn pow10(self, n: i32) -> Self;
244    fn from_bits(u: Self::Unsigned) -> Self;
245    fn to_bits(self) -> Self::Unsigned;
246    fn is_sign_positive(self) -> bool;
247
248    /// Returns true if the float is a denormal.
249    #[inline]
250    fn is_denormal(self) -> bool {
251        self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO
252    }
253
254    /// Returns true if the float is a NaN or Infinite.
255    #[inline]
256    fn is_special(self) -> bool {
257        self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK
258    }
259
260    /// Returns true if the float is infinite.
261    #[inline]
262    fn is_inf(self) -> bool {
263        self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) == Self::Unsigned::ZERO
264    }
265
266    /// Get exponent component from the float.
267    #[inline]
268    fn exponent(self) -> i32 {
269        if self.is_denormal() {
270            return Self::DENORMAL_EXPONENT;
271        }
272
273        let bits = self.to_bits();
274        let biased_e = ((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_u32();
275        biased_e as i32 - Self::EXPONENT_BIAS
276    }
277
278    /// Get mantissa (significand) component from float.
279    #[inline]
280    fn mantissa(self) -> Self::Unsigned {
281        let bits = self.to_bits();
282        let s = bits & Self::MANTISSA_MASK;
283        if !self.is_denormal() {
284            s + Self::HIDDEN_BIT_MASK
285        } else {
286            s
287        }
288    }
289
290    /// Get next greater float for a positive float.
291    /// Value must be >= 0.0 and < INFINITY.
292    #[inline]
293    fn next_positive(self) -> Self {
294        debug_assert!(self.is_sign_positive() && !self.is_inf());
295        Self::from_bits(self.to_bits() + Self::Unsigned::as_cast(1u32))
296    }
297
298    /// Round a positive number to even.
299    #[inline]
300    fn round_positive_even(self) -> Self {
301        if self.mantissa() & Self::Unsigned::as_cast(1u32) == Self::Unsigned::as_cast(1u32) {
302            self.next_positive()
303        } else {
304            self
305        }
306    }
307}
308
309impl Float for f32 {
310    type Unsigned = u32;
311
312    const ZERO: f32 = 0.0;
313    const MAX_DIGITS: usize = 114;
314    const EXPONENT_MASK: u32 = 0x7F800000;
315    const HIDDEN_BIT_MASK: u32 = 0x00800000;
316    const MANTISSA_MASK: u32 = 0x007FFFFF;
317    const INFINITY_BITS: u32 = 0x7F800000;
318    const MANTISSA_SIZE: i32 = 23;
319    const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE;
320    const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
321    const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS;
322    const DEFAULT_SHIFT: i32 = u64::FULL - f32::MANTISSA_SIZE - 1;
323    const CARRY_MASK: u64 = 0x1000000;
324
325    #[inline]
326    fn exponent_limit() -> (i32, i32) {
327        (-10, 10)
328    }
329
330    #[inline]
331    fn mantissa_limit() -> i32 {
332        7
333    }
334
335    #[inline]
336    fn pow10(self, n: i32) -> f32 {
337        // Check the exponent is within bounds in debug builds.
338        debug_assert!({
339            let (min, max) = Self::exponent_limit();
340            n >= min && n <= max
341        });
342
343        if n > 0 {
344            self * F32_POW10[n as usize]
345        } else {
346            self / F32_POW10[-n as usize]
347        }
348    }
349
350    #[inline]
351    fn from_bits(u: u32) -> f32 {
352        f32::from_bits(u)
353    }
354
355    #[inline]
356    fn to_bits(self) -> u32 {
357        f32::to_bits(self)
358    }
359
360    #[inline]
361    fn is_sign_positive(self) -> bool {
362        f32::is_sign_positive(self)
363    }
364}
365
366impl Float for f64 {
367    type Unsigned = u64;
368
369    const ZERO: f64 = 0.0;
370    const MAX_DIGITS: usize = 769;
371    const EXPONENT_MASK: u64 = 0x7FF0000000000000;
372    const HIDDEN_BIT_MASK: u64 = 0x0010000000000000;
373    const MANTISSA_MASK: u64 = 0x000FFFFFFFFFFFFF;
374    const INFINITY_BITS: u64 = 0x7FF0000000000000;
375    const MANTISSA_SIZE: i32 = 52;
376    const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE;
377    const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
378    const MAX_EXPONENT: i32 = 0x7FF - Self::EXPONENT_BIAS;
379    const DEFAULT_SHIFT: i32 = u64::FULL - f64::MANTISSA_SIZE - 1;
380    const CARRY_MASK: u64 = 0x20000000000000;
381
382    #[inline]
383    fn exponent_limit() -> (i32, i32) {
384        (-22, 22)
385    }
386
387    #[inline]
388    fn mantissa_limit() -> i32 {
389        15
390    }
391
392    #[inline]
393    fn pow10(self, n: i32) -> f64 {
394        // Check the exponent is within bounds in debug builds.
395        debug_assert!({
396            let (min, max) = Self::exponent_limit();
397            n >= min && n <= max
398        });
399
400        if n > 0 {
401            self * F64_POW10[n as usize]
402        } else {
403            self / F64_POW10[-n as usize]
404        }
405    }
406
407    #[inline]
408    fn from_bits(u: u64) -> f64 {
409        f64::from_bits(u)
410    }
411
412    #[inline]
413    fn to_bits(self) -> u64 {
414        f64::to_bits(self)
415    }
416
417    #[inline]
418    fn is_sign_positive(self) -> bool {
419        f64::is_sign_positive(self)
420    }
421}