mesh_loader/utils/float/
number.rs1use super::float::RawFloat;
4
5#[rustfmt::skip]
6static INT_POW10: [u64; 16] = [
7 1,
8 10,
9 100,
10 1000,
11 10000,
12 100000,
13 1000000,
14 10000000,
15 100000000,
16 1000000000,
17 10000000000,
18 100000000000,
19 1000000000000,
20 10000000000000,
21 100000000000000,
22 1000000000000000,
23];
24
25#[derive(Clone, Copy, Default, PartialEq, Eq)]
26pub(crate) struct Number {
27 pub(crate) exponent: i64,
28 pub(crate) mantissa: u64,
29 pub(crate) negative: bool,
30 pub(crate) many_digits: bool,
31}
32
33impl Number {
34 #[inline]
36 fn is_fast_path<F: RawFloat>(&self) -> bool {
37 F::MIN_EXPONENT_FAST_PATH <= self.exponent
38 && self.exponent <= F::MAX_EXPONENT_DISGUISED_FAST_PATH
39 && self.mantissa <= F::MAX_MANTISSA_FAST_PATH
40 && !self.many_digits
41 }
42
43 #[inline]
53 pub(crate) fn try_fast_path<F: RawFloat>(&self) -> Option<F> {
54 if self.is_fast_path::<F>() {
55 let mut value = if self.exponent <= F::MAX_EXPONENT_FAST_PATH {
56 let value = F::from_u64(self.mantissa);
58 if self.exponent < 0 {
59 value / F::pow10_fast_path((-self.exponent) as usize)
60 } else {
61 value * F::pow10_fast_path(self.exponent as usize)
62 }
63 } else {
64 let shift = self.exponent - F::MAX_EXPONENT_FAST_PATH;
66 let mantissa = self.mantissa.checked_mul(INT_POW10[shift as usize])?;
67 if mantissa > F::MAX_MANTISSA_FAST_PATH {
68 return None;
69 }
70 F::from_u64(mantissa) * F::pow10_fast_path(F::MAX_EXPONENT_FAST_PATH as usize)
71 };
72 if self.negative {
73 value = -value;
74 }
75 Some(value)
76 } else {
77 None
78 }
79 }
80}