| 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. |
| 2 | |
| 3 | //! Utilities for Rust numbers. |
| 4 | |
| 5 | use 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. |
| 9 | const 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. |
| 25 | const 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`. |
| 52 | pub 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 | |
| 61 | macro_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 | |
| 99 | as_primitive_impl! { u32 u64 u128 usize f32 f64 } |
| 100 | |
| 101 | /// An interface for casting between machine scalars. |
| 102 | pub 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 | |
| 108 | macro_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 | |
| 119 | as_cast_impl!(u32, as_u32); |
| 120 | as_cast_impl!(u64, as_u64); |
| 121 | as_cast_impl!(u128, as_u128); |
| 122 | as_cast_impl!(usize, as_usize); |
| 123 | as_cast_impl!(f32, as_f32); |
| 124 | as_cast_impl!(f64, as_f64); |
| 125 | |
| 126 | /// Numerical type trait. |
| 127 | pub trait Number: AsCast + ops::Add<Output = Self> {} |
| 128 | |
| 129 | macro_rules! number_impl { |
| 130 | ($($ty:ident)*) => { |
| 131 | $( |
| 132 | impl Number for $ty {} |
| 133 | )* |
| 134 | }; |
| 135 | } |
| 136 | |
| 137 | number_impl! { u32 u64 u128 usize f32 f64 } |
| 138 | |
| 139 | /// Defines a trait that supports integral operations. |
| 140 | pub trait Integer: Number + ops::BitAnd<Output = Self> + ops::Shr<i32, Output = Self> { |
| 141 | const ZERO: Self; |
| 142 | } |
| 143 | |
| 144 | macro_rules! integer_impl { |
| 145 | ($($ty:tt)*) => { |
| 146 | $( |
| 147 | impl Integer for $ty { |
| 148 | const ZERO: Self = 0; |
| 149 | } |
| 150 | )* |
| 151 | }; |
| 152 | } |
| 153 | |
| 154 | integer_impl! { u32 u64 u128 usize } |
| 155 | |
| 156 | /// Type trait for the mantissa type. |
| 157 | pub 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 | |
| 168 | impl 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. |
| 175 | pub 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 | |
| 314 | impl 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 | |
| 378 | impl 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 | |