core/num/dec2flt/
float.rs1use core::f64;
4
5use crate::fmt::{Debug, LowerExp};
6use crate::num::FpCategory;
7use crate::ops::{self, Add, Div, Mul, Neg};
8
9pub trait CastInto<T: Copy>: Copy {
11 fn cast(self) -> T;
12}
13
14pub trait Integer:
16 Sized
17 + Clone
18 + Copy
19 + Debug
20 + ops::Shr<u32, Output = Self>
21 + ops::Shl<u32, Output = Self>
22 + ops::BitAnd<Output = Self>
23 + ops::BitOr<Output = Self>
24 + PartialEq
25 + CastInto<i16>
26{
27 const ZERO: Self;
28 const ONE: Self;
29}
30
31macro_rules! int {
32 ($($ty:ty),+) => {
33 $(
34 impl CastInto<i16> for $ty {
35 fn cast(self) -> i16 {
36 self as i16
37 }
38 }
39
40 impl Integer for $ty {
41 const ZERO: Self = 0;
42 const ONE: Self = 1;
43 }
44 )+
45 }
46}
47
48int!(u32, u64);
49
50#[doc(hidden)]
56pub trait RawFloat:
57 Sized
58 + Div<Output = Self>
59 + Neg<Output = Self>
60 + Mul<Output = Self>
61 + Add<Output = Self>
62 + LowerExp
63 + PartialEq
64 + PartialOrd
65 + Default
66 + Clone
67 + Copy
68 + Debug
69{
70 type Int: Integer + Into<u64>;
72
73 const INFINITY: Self;
76 const NEG_INFINITY: Self;
77 const NAN: Self;
78 const NEG_NAN: Self;
79
80 const BITS: u32;
82
83 const SIG_TOTAL_BITS: u32;
85
86 const EXP_MASK: Self::Int;
87 const SIG_MASK: Self::Int;
88
89 const SIG_BITS: u32 = Self::SIG_TOTAL_BITS - 1;
91
92 const EXP_BITS: u32 = Self::BITS - Self::SIG_BITS - 1;
94
95 const EXP_SAT: u32 = (1 << Self::EXP_BITS) - 1;
100
101 const INFINITE_POWER: i32 = Self::EXP_SAT as i32;
103
104 const EXP_BIAS: u32 = Self::EXP_SAT >> 1;
106
107 const EXP_MIN: i32 = -(Self::EXP_BIAS as i32 - 1);
109
110 const MIN_EXPONENT_ROUND_TO_EVEN: i32;
129 const MAX_EXPONENT_ROUND_TO_EVEN: i32;
130
131 const LARGEST_POWER_OF_TEN: i32 = {
138 let largest_pow2 = Self::EXP_BIAS + 1;
139 pow2_to_pow10(largest_pow2 as i64) as i32
140 };
141
142 const SMALLEST_POWER_OF_TEN: i32;
153
154 const MAX_EXPONENT_FAST_PATH: i64 = {
157 let log2_5 = f64::consts::LOG2_10 - 1.0;
158 (Self::SIG_TOTAL_BITS as f64 / log2_5) as i64
159 };
160
161 const MIN_EXPONENT_FAST_PATH: i64 = -Self::MAX_EXPONENT_FAST_PATH;
163
164 const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 =
167 Self::MAX_EXPONENT_FAST_PATH + (Self::SIG_TOTAL_BITS as f64 / f64::consts::LOG2_10) as i64;
168
169 const MAX_MANTISSA_FAST_PATH: u64 = 1 << Self::SIG_TOTAL_BITS;
171
172 fn from_u64(v: u64) -> Self;
177
178 fn from_u64_bits(v: u64) -> Self;
180
181 fn pow10_fast_path(exponent: usize) -> Self;
183
184 fn classify(self) -> FpCategory;
186
187 fn to_bits(self) -> Self::Int;
189
190 fn integer_decode(self) -> (u64, i16, i8) {
196 let bits = self.to_bits();
197 let sign: i8 = if bits >> (Self::BITS - 1) == Self::Int::ZERO { 1 } else { -1 };
198 let mut exponent: i16 = ((bits & Self::EXP_MASK) >> Self::SIG_BITS).cast();
199 let mantissa = if exponent == 0 {
200 (bits & Self::SIG_MASK) << 1
201 } else {
202 (bits & Self::SIG_MASK) | (Self::Int::ONE << Self::SIG_BITS)
203 };
204 exponent -= (Self::EXP_BIAS + Self::SIG_BITS) as i16;
206 (mantissa.into(), exponent, sign)
207 }
208}
209
210const fn pow2_to_pow10(a: i64) -> i64 {
212 let res = (a as f64) / f64::consts::LOG2_10;
213 res as i64
214}
215
216impl RawFloat for f32 {
217 type Int = u32;
218
219 const INFINITY: Self = f32::INFINITY;
220 const NEG_INFINITY: Self = f32::NEG_INFINITY;
221 const NAN: Self = f32::NAN;
222 const NEG_NAN: Self = -f32::NAN;
223
224 const BITS: u32 = 32;
225 const SIG_TOTAL_BITS: u32 = Self::MANTISSA_DIGITS;
226 const EXP_MASK: Self::Int = Self::EXP_MASK;
227 const SIG_MASK: Self::Int = Self::MAN_MASK;
228
229 const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -17;
230 const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 10;
231 const SMALLEST_POWER_OF_TEN: i32 = -65;
232
233 #[inline]
234 fn from_u64(v: u64) -> Self {
235 debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH);
236 v as _
237 }
238
239 #[inline]
240 fn from_u64_bits(v: u64) -> Self {
241 f32::from_bits((v & 0xFFFFFFFF) as u32)
242 }
243
244 fn pow10_fast_path(exponent: usize) -> Self {
245 #[allow(clippy::use_self)]
246 const TABLE: [f32; 16] =
247 [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 0., 0., 0., 0., 0.];
248 TABLE[exponent & 15]
249 }
250
251 fn to_bits(self) -> Self::Int {
252 self.to_bits()
253 }
254
255 fn classify(self) -> FpCategory {
256 self.classify()
257 }
258}
259
260impl RawFloat for f64 {
261 type Int = u64;
262
263 const INFINITY: Self = Self::INFINITY;
264 const NEG_INFINITY: Self = Self::NEG_INFINITY;
265 const NAN: Self = Self::NAN;
266 const NEG_NAN: Self = -Self::NAN;
267
268 const BITS: u32 = 64;
269 const SIG_TOTAL_BITS: u32 = Self::MANTISSA_DIGITS;
270 const EXP_MASK: Self::Int = Self::EXP_MASK;
271 const SIG_MASK: Self::Int = Self::MAN_MASK;
272
273 const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -4;
274 const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 23;
275 const SMALLEST_POWER_OF_TEN: i32 = -342;
276
277 #[inline]
278 fn from_u64(v: u64) -> Self {
279 debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH);
280 v as _
281 }
282
283 #[inline]
284 fn from_u64_bits(v: u64) -> Self {
285 f64::from_bits(v)
286 }
287
288 fn pow10_fast_path(exponent: usize) -> Self {
289 const TABLE: [f64; 32] = [
290 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
291 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 0., 0., 0., 0., 0., 0., 0., 0., 0.,
292 ];
293 TABLE[exponent & 31]
294 }
295
296 fn to_bits(self) -> Self::Int {
297 self.to_bits()
298 }
299
300 fn classify(self) -> FpCategory {
301 self.classify()
302 }
303}