mesh_loader/utils/float/
float.rs
1use core::ops::{Div, Mul, Neg};
4
5pub trait RawFloat: Copy + Div<Output = Self> + Neg<Output = Self> + Mul<Output = Self> {
7 const INFINITY: Self;
8 const NEG_INFINITY: Self;
9 const NAN: Self;
10 const NEG_NAN: Self;
11
12 const MANTISSA_EXPLICIT_BITS: usize;
14
15 const MIN_EXPONENT_ROUND_TO_EVEN: i32;
34 const MAX_EXPONENT_ROUND_TO_EVEN: i32;
35
36 const MIN_EXPONENT_FAST_PATH: i64;
38
39 const MAX_EXPONENT_FAST_PATH: i64;
41
42 const MAX_EXPONENT_DISGUISED_FAST_PATH: i64;
45
46 const MINIMUM_EXPONENT: i32;
48
49 const INFINITE_POWER: i32;
51
52 const SIGN_INDEX: usize;
54
55 const SMALLEST_POWER_OF_TEN: i32;
57
58 const LARGEST_POWER_OF_TEN: i32;
60
61 const MAX_MANTISSA_FAST_PATH: u64 = 2_u64 << Self::MANTISSA_EXPLICIT_BITS;
63
64 fn from_u64(v: u64) -> Self;
69
70 fn from_u64_bits(v: u64) -> Self;
72
73 fn pow10_fast_path(exponent: usize) -> Self;
75}
76
77impl RawFloat for f32 {
78 const INFINITY: Self = f32::INFINITY;
79 const NEG_INFINITY: Self = f32::NEG_INFINITY;
80 const NAN: Self = f32::NAN;
81 const NEG_NAN: Self = -f32::NAN;
82
83 const MANTISSA_EXPLICIT_BITS: usize = 23;
84 const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -17;
85 const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 10;
86 const MIN_EXPONENT_FAST_PATH: i64 = -10; const MAX_EXPONENT_FAST_PATH: i64 = 10;
88 const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = 17;
89 const MINIMUM_EXPONENT: i32 = -127;
90 const INFINITE_POWER: i32 = 0xFF;
91 const SIGN_INDEX: usize = 31;
92 const SMALLEST_POWER_OF_TEN: i32 = -65;
93 const LARGEST_POWER_OF_TEN: i32 = 38;
94
95 #[inline]
96 fn from_u64(v: u64) -> Self {
97 debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH);
98 v as f32
99 }
100
101 #[inline]
102 fn from_u64_bits(v: u64) -> Self {
103 f32::from_bits((v & 0xFFFFFFFF) as u32)
104 }
105
106 #[inline]
107 fn pow10_fast_path(exponent: usize) -> Self {
108 static TABLE: [f32; 16] = [
109 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 0., 0., 0., 0., 0.,
110 ];
111 TABLE[exponent & 15]
112 }
113}
114
115impl RawFloat for f64 {
116 const INFINITY: Self = f64::INFINITY;
117 const NEG_INFINITY: Self = f64::NEG_INFINITY;
118 const NAN: Self = f64::NAN;
119 const NEG_NAN: Self = -f64::NAN;
120
121 const MANTISSA_EXPLICIT_BITS: usize = 52;
122 const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -4;
123 const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 23;
124 const MIN_EXPONENT_FAST_PATH: i64 = -22; const MAX_EXPONENT_FAST_PATH: i64 = 22;
126 const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = 37;
127 const MINIMUM_EXPONENT: i32 = -1023;
128 const INFINITE_POWER: i32 = 0x7FF;
129 const SIGN_INDEX: usize = 63;
130 const SMALLEST_POWER_OF_TEN: i32 = -342;
131 const LARGEST_POWER_OF_TEN: i32 = 308;
132
133 #[inline]
134 fn from_u64(v: u64) -> Self {
135 debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH);
136 v as f64
137 }
138
139 #[inline]
140 fn from_u64_bits(v: u64) -> Self {
141 f64::from_bits(v)
142 }
143
144 #[inline]
145 fn pow10_fast_path(exponent: usize) -> Self {
146 static TABLE: [f64; 32] = [
147 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
148 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 0., 0., 0., 0., 0., 0., 0., 0., 0.,
149 ];
150 TABLE[exponent & 31]
151 }
152}