1 // Adapted from https://github.com/Alexhuszagh/rust-lexical.
2 
3 //! Utilities for Rust numbers.
4 
5 use crate::lib::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.
9 const 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.
25 const 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`.
52 pub trait AsPrimitive: Sized + Copy + PartialOrd {
as_u32(self) -> u3253     fn as_u32(self) -> u32;
as_u64(self) -> u6454     fn as_u64(self) -> u64;
as_u128(self) -> u12855     fn as_u128(self) -> u128;
as_usize(self) -> usize56     fn as_usize(self) -> usize;
as_f32(self) -> f3257     fn as_f32(self) -> f32;
as_f64(self) -> f6458     fn as_f64(self) -> f64;
59 }
60 
61 macro_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 
99 as_primitive_impl! { u32 u64 u128 usize f32 f64 }
100 
101 /// An interface for casting between machine scalars.
102 pub trait AsCast: AsPrimitive {
103     /// Creates a number from another value that can be converted into
104     /// a primitive via the `AsPrimitive` trait.
as_cast<N: AsPrimitive>(n: N) -> Self105     fn as_cast<N: AsPrimitive>(n: N) -> Self;
106 }
107 
108 macro_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 
119 as_cast_impl!(u32, as_u32);
120 as_cast_impl!(u64, as_u64);
121 as_cast_impl!(u128, as_u128);
122 as_cast_impl!(usize, as_usize);
123 as_cast_impl!(f32, as_f32);
124 as_cast_impl!(f64, as_f64);
125 
126 /// Numerical type trait.
127 pub trait Number: AsCast + ops::Add<Output = Self> {}
128 
129 macro_rules! number_impl {
130     ($($ty:ident)*) => {
131         $(
132             impl Number for $ty {}
133         )*
134     };
135 }
136 
137 number_impl! { u32 u64 u128 usize f32 f64 }
138 
139 /// Defines a trait that supports integral operations.
140 pub trait Integer: Number + ops::BitAnd<Output = Self> + ops::Shr<i32, Output = Self> {
141     const ZERO: Self;
142 }
143 
144 macro_rules! integer_impl {
145     ($($ty:tt)*) => {
146         $(
147             impl Integer for $ty {
148                 const ZERO: Self = 0;
149             }
150         )*
151     };
152 }
153 
154 integer_impl! { u32 u64 u128 usize }
155 
156 /// Type trait for the mantissa type.
157 pub 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 
168 impl 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.
175 pub 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 sign bit.
210     const SIGN_MASK: Self::Unsigned;
211     /// Bitmask for the exponent, including the hidden bit.
212     const EXPONENT_MASK: Self::Unsigned;
213     /// Bitmask for the hidden bit in exponent, which is an implicit 1 in the fraction.
214     const HIDDEN_BIT_MASK: Self::Unsigned;
215     /// Bitmask for the mantissa (fraction), excluding the hidden bit.
216     const MANTISSA_MASK: Self::Unsigned;
217 
218     // PROPERTIES
219 
220     /// Positive infinity as bits.
221     const INFINITY_BITS: Self::Unsigned;
222     /// Positive infinity as bits.
223     const NEGATIVE_INFINITY_BITS: Self::Unsigned;
224     /// Size of the significand (mantissa) without hidden bit.
225     const MANTISSA_SIZE: i32;
226     /// Bias of the exponet
227     const EXPONENT_BIAS: i32;
228     /// Exponent portion of a denormal float.
229     const DENORMAL_EXPONENT: i32;
230     /// Maximum exponent value in float.
231     const MAX_EXPONENT: i32;
232 
233     // ROUNDING
234 
235     /// Default number of bits to shift (or 64 - mantissa size - 1).
236     const DEFAULT_SHIFT: i32;
237     /// Mask to determine if a full-carry occurred (1 in bit above hidden bit).
238     const CARRY_MASK: u64;
239 
240     /// Get min and max exponent limits (exact) from radix.
exponent_limit() -> (i32, i32)241     fn exponent_limit() -> (i32, i32);
242 
243     /// Get the number of digits that can be shifted from exponent to mantissa.
mantissa_limit() -> i32244     fn mantissa_limit() -> i32;
245 
246     // Re-exported methods from std.
pow10(self, n: i32) -> Self247     fn pow10(self, n: i32) -> Self;
from_bits(u: Self::Unsigned) -> Self248     fn from_bits(u: Self::Unsigned) -> Self;
to_bits(self) -> Self::Unsigned249     fn to_bits(self) -> Self::Unsigned;
is_sign_positive(self) -> bool250     fn is_sign_positive(self) -> bool;
is_sign_negative(self) -> bool251     fn is_sign_negative(self) -> bool;
252 
253     /// Returns true if the float is a denormal.
254     #[inline]
is_denormal(self) -> bool255     fn is_denormal(self) -> bool {
256         self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO
257     }
258 
259     /// Returns true if the float is a NaN or Infinite.
260     #[inline]
is_special(self) -> bool261     fn is_special(self) -> bool {
262         self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK
263     }
264 
265     /// Returns true if the float is infinite.
266     #[inline]
is_inf(self) -> bool267     fn is_inf(self) -> bool {
268         self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) == Self::Unsigned::ZERO
269     }
270 
271     /// Get exponent component from the float.
272     #[inline]
exponent(self) -> i32273     fn exponent(self) -> i32 {
274         if self.is_denormal() {
275             return Self::DENORMAL_EXPONENT;
276         }
277 
278         let bits = self.to_bits();
279         let biased_e = ((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_u32();
280         biased_e as i32 - Self::EXPONENT_BIAS
281     }
282 
283     /// Get mantissa (significand) component from float.
284     #[inline]
mantissa(self) -> Self::Unsigned285     fn mantissa(self) -> Self::Unsigned {
286         let bits = self.to_bits();
287         let s = bits & Self::MANTISSA_MASK;
288         if !self.is_denormal() {
289             s + Self::HIDDEN_BIT_MASK
290         } else {
291             s
292         }
293     }
294 
295     /// Get next greater float for a positive float.
296     /// Value must be >= 0.0 and < INFINITY.
297     #[inline]
next_positive(self) -> Self298     fn next_positive(self) -> Self {
299         debug_assert!(self.is_sign_positive() && !self.is_inf());
300         Self::from_bits(self.to_bits() + Self::Unsigned::as_cast(1u32))
301     }
302 
303     /// Round a positive number to even.
304     #[inline]
round_positive_even(self) -> Self305     fn round_positive_even(self) -> Self {
306         if self.mantissa() & Self::Unsigned::as_cast(1u32) == Self::Unsigned::as_cast(1u32) {
307             self.next_positive()
308         } else {
309             self
310         }
311     }
312 }
313 
314 impl Float for f32 {
315     type Unsigned = u32;
316 
317     const ZERO: f32 = 0.0;
318     const MAX_DIGITS: usize = 114;
319     const SIGN_MASK: u32 = 0x80000000;
320     const EXPONENT_MASK: u32 = 0x7F800000;
321     const HIDDEN_BIT_MASK: u32 = 0x00800000;
322     const MANTISSA_MASK: u32 = 0x007FFFFF;
323     const INFINITY_BITS: u32 = 0x7F800000;
324     const NEGATIVE_INFINITY_BITS: u32 = Self::INFINITY_BITS | Self::SIGN_MASK;
325     const MANTISSA_SIZE: i32 = 23;
326     const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE;
327     const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
328     const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS;
329     const DEFAULT_SHIFT: i32 = u64::FULL - f32::MANTISSA_SIZE - 1;
330     const CARRY_MASK: u64 = 0x1000000;
331 
332     #[inline]
exponent_limit() -> (i32, i32)333     fn exponent_limit() -> (i32, i32) {
334         (-10, 10)
335     }
336 
337     #[inline]
mantissa_limit() -> i32338     fn mantissa_limit() -> i32 {
339         7
340     }
341 
342     #[inline]
pow10(self, n: i32) -> f32343     fn pow10(self, n: i32) -> f32 {
344         // Check the exponent is within bounds in debug builds.
345         debug_assert!({
346             let (min, max) = Self::exponent_limit();
347             n >= min && n <= max
348         });
349 
350         if n > 0 {
351             self * F32_POW10[n as usize]
352         } else {
353             self / F32_POW10[-n as usize]
354         }
355     }
356 
357     #[inline]
from_bits(u: u32) -> f32358     fn from_bits(u: u32) -> f32 {
359         f32::from_bits(u)
360     }
361 
362     #[inline]
to_bits(self) -> u32363     fn to_bits(self) -> u32 {
364         f32::to_bits(self)
365     }
366 
367     #[inline]
is_sign_positive(self) -> bool368     fn is_sign_positive(self) -> bool {
369         f32::is_sign_positive(self)
370     }
371 
372     #[inline]
is_sign_negative(self) -> bool373     fn is_sign_negative(self) -> bool {
374         f32::is_sign_negative(self)
375     }
376 }
377 
378 impl Float for f64 {
379     type Unsigned = u64;
380 
381     const ZERO: f64 = 0.0;
382     const MAX_DIGITS: usize = 769;
383     const SIGN_MASK: u64 = 0x8000000000000000;
384     const EXPONENT_MASK: u64 = 0x7FF0000000000000;
385     const HIDDEN_BIT_MASK: u64 = 0x0010000000000000;
386     const MANTISSA_MASK: u64 = 0x000FFFFFFFFFFFFF;
387     const INFINITY_BITS: u64 = 0x7FF0000000000000;
388     const NEGATIVE_INFINITY_BITS: u64 = Self::INFINITY_BITS | Self::SIGN_MASK;
389     const MANTISSA_SIZE: i32 = 52;
390     const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE;
391     const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
392     const MAX_EXPONENT: i32 = 0x7FF - Self::EXPONENT_BIAS;
393     const DEFAULT_SHIFT: i32 = u64::FULL - f64::MANTISSA_SIZE - 1;
394     const CARRY_MASK: u64 = 0x20000000000000;
395 
396     #[inline]
exponent_limit() -> (i32, i32)397     fn exponent_limit() -> (i32, i32) {
398         (-22, 22)
399     }
400 
401     #[inline]
mantissa_limit() -> i32402     fn mantissa_limit() -> i32 {
403         15
404     }
405 
406     #[inline]
pow10(self, n: i32) -> f64407     fn pow10(self, n: i32) -> f64 {
408         // Check the exponent is within bounds in debug builds.
409         debug_assert!({
410             let (min, max) = Self::exponent_limit();
411             n >= min && n <= max
412         });
413 
414         if n > 0 {
415             self * F64_POW10[n as usize]
416         } else {
417             self / F64_POW10[-n as usize]
418         }
419     }
420 
421     #[inline]
from_bits(u: u64) -> f64422     fn from_bits(u: u64) -> f64 {
423         f64::from_bits(u)
424     }
425 
426     #[inline]
to_bits(self) -> u64427     fn to_bits(self) -> u64 {
428         f64::to_bits(self)
429     }
430 
431     #[inline]
is_sign_positive(self) -> bool432     fn is_sign_positive(self) -> bool {
433         f64::is_sign_positive(self)
434     }
435 
436     #[inline]
is_sign_negative(self) -> bool437     fn is_sign_negative(self) -> bool {
438         f64::is_sign_negative(self)
439     }
440 }
441