1#![doc(hidden)]
4#![unstable(
5 feature = "num_internals",
6 reason = "internal routines only exposed for testing",
7 issue = "none"
8)]
9
10use crate::num::FpCategory;
11use crate::{f64, fmt, ops};
12
13pub trait CastInto<T: Copy>: Copy {
15 fn cast(self) -> T;
16}
17
18pub trait Int:
20 Sized
21 + Clone
22 + Copy
23 + fmt::Debug
24 + ops::Shr<u32, Output = Self>
25 + ops::Shl<u32, Output = Self>
26 + ops::BitAnd<Output = Self>
27 + ops::BitOr<Output = Self>
28 + PartialEq
29 + CastInto<i16>
30{
31 const ZERO: Self;
32 const ONE: Self;
33}
34
35macro_rules! int {
36 ($($ty:ty),+) => {
37 $(
38 impl CastInto<i16> for $ty {
39 fn cast(self) -> i16 {
40 self as i16
41 }
42 }
43
44 impl Int for $ty {
45 const ZERO: Self = 0;
46 const ONE: Self = 1;
47 }
48 )+
49 }
50}
51
52int!(u16, u32, u64);
53
54#[doc(hidden)]
56pub trait Float:
57 Sized
58 + ops::Div<Output = Self>
59 + ops::Neg<Output = Self>
60 + ops::Mul<Output = Self>
61 + ops::Add<Output = Self>
62 + fmt::Debug
63 + PartialEq
64 + PartialOrd
65 + Default
66 + Clone
67 + Copy
68{
69 type Int: Int + Into<u64>;
71
72 const INFINITY: Self;
75 const NEG_INFINITY: Self;
76 const NAN: Self;
77 const NEG_NAN: Self;
78
79 const BITS: u32;
81
82 const SIG_TOTAL_BITS: u32;
84
85 const EXP_MASK: Self::Int;
86 const SIG_MASK: Self::Int;
87
88 const SIG_BITS: u32 = Self::SIG_TOTAL_BITS - 1;
90
91 const EXP_BITS: u32 = Self::BITS - Self::SIG_BITS - 1;
93
94 const EXP_SAT: u32 = (1 << Self::EXP_BITS) - 1;
99
100 const INFINITE_POWER: i32 = Self::EXP_SAT as i32;
102
103 const EXP_BIAS: u32 = Self::EXP_SAT >> 1;
105
106 const EXP_MIN: i32 = -(Self::EXP_BIAS as i32 - 1);
108
109 const MIN_EXPONENT_ROUND_TO_EVEN: i32;
128 const MAX_EXPONENT_ROUND_TO_EVEN: i32;
129
130 const LARGEST_POWER_OF_TEN: i32 = {
135 let largest_pow2 = Self::EXP_BIAS + 1;
136 pow2_to_pow10(largest_pow2 as i64) as i32
137 };
138
139 const SMALLEST_POWER_OF_TEN: i32;
150
151 fn classify(self) -> FpCategory;
153
154 fn to_bits(self) -> Self::Int;
156}
157
158#[doc(hidden)]
161pub trait FloatExt: Float {
162 fn from_u64_bits(v: u64) -> Self;
164
165 fn integer_decode(self) -> (u64, i16, i8) {
176 let bits = self.to_bits();
177 let sign: i8 = if bits >> (Self::BITS - 1) == Self::Int::ZERO { 1 } else { -1 };
178 let mut exponent: i16 = ((bits & Self::EXP_MASK) >> Self::SIG_BITS).cast();
179 let mantissa = if exponent == 0 {
180 (bits & Self::SIG_MASK) << 1
181 } else {
182 (bits & Self::SIG_MASK) | (Self::Int::ONE << Self::SIG_BITS)
183 };
184 exponent -= (Self::EXP_BIAS + Self::SIG_BITS) as i16;
186 (mantissa.into(), exponent, sign)
187 }
188}
189
190const fn pow2_to_pow10(a: i64) -> i64 {
192 let res = (a as f64) / f64::consts::LOG2_10;
193 res as i64
194}
195
196#[cfg(target_has_reliable_f16)]
197impl Float for f16 {
198 type Int = u16;
199
200 const INFINITY: Self = Self::INFINITY;
201 const NEG_INFINITY: Self = Self::NEG_INFINITY;
202 const NAN: Self = Self::NAN;
203 const NEG_NAN: Self = -Self::NAN;
204
205 const BITS: u32 = 16;
206 const SIG_TOTAL_BITS: u32 = Self::MANTISSA_DIGITS;
207 const EXP_MASK: Self::Int = Self::EXP_MASK;
208 const SIG_MASK: Self::Int = Self::MAN_MASK;
209
210 const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -22;
211 const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 5;
212 const SMALLEST_POWER_OF_TEN: i32 = -27;
213
214 fn to_bits(self) -> Self::Int {
215 self.to_bits()
216 }
217
218 fn classify(self) -> FpCategory {
219 self.classify()
220 }
221}
222
223#[cfg(target_has_reliable_f16)]
224impl FloatExt for f16 {
225 #[inline]
226 fn from_u64_bits(v: u64) -> Self {
227 Self::from_bits((v & 0xFFFF) as u16)
228 }
229}
230
231impl Float for f32 {
232 type Int = u32;
233
234 const INFINITY: Self = f32::INFINITY;
235 const NEG_INFINITY: Self = f32::NEG_INFINITY;
236 const NAN: Self = f32::NAN;
237 const NEG_NAN: Self = -f32::NAN;
238
239 const BITS: u32 = 32;
240 const SIG_TOTAL_BITS: u32 = Self::MANTISSA_DIGITS;
241 const EXP_MASK: Self::Int = Self::EXP_MASK;
242 const SIG_MASK: Self::Int = Self::MAN_MASK;
243
244 const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -17;
245 const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 10;
246 const SMALLEST_POWER_OF_TEN: i32 = -65;
247
248 fn to_bits(self) -> Self::Int {
249 self.to_bits()
250 }
251
252 fn classify(self) -> FpCategory {
253 self.classify()
254 }
255}
256
257impl FloatExt for f32 {
258 #[inline]
259 fn from_u64_bits(v: u64) -> Self {
260 f32::from_bits((v & 0xFFFFFFFF) as u32)
261 }
262}
263
264impl Float for f64 {
265 type Int = u64;
266
267 const INFINITY: Self = Self::INFINITY;
268 const NEG_INFINITY: Self = Self::NEG_INFINITY;
269 const NAN: Self = Self::NAN;
270 const NEG_NAN: Self = -Self::NAN;
271
272 const BITS: u32 = 64;
273 const SIG_TOTAL_BITS: u32 = Self::MANTISSA_DIGITS;
274 const EXP_MASK: Self::Int = Self::EXP_MASK;
275 const SIG_MASK: Self::Int = Self::MAN_MASK;
276
277 const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -4;
278 const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 23;
279 const SMALLEST_POWER_OF_TEN: i32 = -342;
280
281 fn to_bits(self) -> Self::Int {
282 self.to_bits()
283 }
284
285 fn classify(self) -> FpCategory {
286 self.classify()
287 }
288}
289
290impl FloatExt for f64 {
291 #[inline]
292 fn from_u64_bits(v: u64) -> Self {
293 f64::from_bits(v)
294 }
295}