1// Adapted from https://github.com/Alexhuszagh/rust-lexical.
2
3//! Utilities for Rust numbers.
4
5use core::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.
9const 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.
25const 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`.
52pub trait AsPrimitive: Sized + Copy + PartialOrd {
53 fn as_u32(self) -> u32;
54 fn as_u64(self) -> u64;
55 fn as_u128(self) -> u128;
56 fn as_usize(self) -> usize;
57 fn as_f32(self) -> f32;
58 fn as_f64(self) -> f64;
59}
60
61macro_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
99as_primitive_impl! { u32 u64 u128 usize f32 f64 }
100
101/// An interface for casting between machine scalars.
102pub trait AsCast: AsPrimitive {
103 /// Creates a number from another value that can be converted into
104 /// a primitive via the `AsPrimitive` trait.
105 fn as_cast<N: AsPrimitive>(n: N) -> Self;
106}
107
108macro_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
119as_cast_impl!(u32, as_u32);
120as_cast_impl!(u64, as_u64);
121as_cast_impl!(u128, as_u128);
122as_cast_impl!(usize, as_usize);
123as_cast_impl!(f32, as_f32);
124as_cast_impl!(f64, as_f64);
125
126/// Numerical type trait.
127pub trait Number: AsCast + ops::Add<Output = Self> {}
128
129macro_rules! number_impl {
130 ($($ty:ident)*) => {
131 $(
132 impl Number for $ty {}
133 )*
134 };
135}
136
137number_impl! { u32 u64 u128 usize f32 f64 }
138
139/// Defines a trait that supports integral operations.
140pub trait Integer: Number + ops::BitAnd<Output = Self> + ops::Shr<i32, Output = Self> {
141 const ZERO: Self;
142}
143
144macro_rules! integer_impl {
145 ($($ty:tt)*) => {
146 $(
147 impl Integer for $ty {
148 const ZERO: Self = 0;
149 }
150 )*
151 };
152}
153
154integer_impl! { u32 u64 u128 usize }
155
156/// Type trait for the mantissa type.
157pub 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
168impl 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.
175pub 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.
241 fn exponent_limit() -> (i32, i32);
242
243 /// Get the number of digits that can be shifted from exponent to mantissa.
244 fn mantissa_limit() -> i32;
245
246 // Re-exported methods from std.
247 fn pow10(self, n: i32) -> Self;
248 fn from_bits(u: Self::Unsigned) -> Self;
249 fn to_bits(self) -> Self::Unsigned;
250 fn is_sign_positive(self) -> bool;
251 fn is_sign_negative(self) -> bool;
252
253 /// Returns true if the float is a denormal.
254 #[inline]
255 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]
261 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]
267 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]
273 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]
285 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]
298 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]
305 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
314impl 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]
333 fn exponent_limit() -> (i32, i32) {
334 (-10, 10)
335 }
336
337 #[inline]
338 fn mantissa_limit() -> i32 {
339 7
340 }
341
342 #[inline]
343 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]
358 fn from_bits(u: u32) -> f32 {
359 f32::from_bits(u)
360 }
361
362 #[inline]
363 fn to_bits(self) -> u32 {
364 f32::to_bits(self)
365 }
366
367 #[inline]
368 fn is_sign_positive(self) -> bool {
369 f32::is_sign_positive(self)
370 }
371
372 #[inline]
373 fn is_sign_negative(self) -> bool {
374 f32::is_sign_negative(self)
375 }
376}
377
378impl 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]
397 fn exponent_limit() -> (i32, i32) {
398 (-22, 22)
399 }
400
401 #[inline]
402 fn mantissa_limit() -> i32 {
403 15
404 }
405
406 #[inline]
407 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]
422 fn from_bits(u: u64) -> f64 {
423 f64::from_bits(u)
424 }
425
426 #[inline]
427 fn to_bits(self) -> u64 {
428 f64::to_bits(self)
429 }
430
431 #[inline]
432 fn is_sign_positive(self) -> bool {
433 f64::is_sign_positive(self)
434 }
435
436 #[inline]
437 fn is_sign_negative(self) -> bool {
438 f64::is_sign_negative(self)
439 }
440}
441