1 // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 3 //! Utilities for Rust numbers. 4 5 use crate::lib::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 { as_u32(self) -> u3253 fn as_u32(self) -> u32; as_u64(self) -> u6454 fn as_u64(self) -> u64; as_u128(self) -> u12855 fn as_u128(self) -> u128; as_usize(self) -> usize56 fn as_usize(self) -> usize; as_f32(self) -> f3257 fn as_f32(self) -> f32; as_f64(self) -> f6458 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. as_cast<N: AsPrimitive>(n: N) -> Self105 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. exponent_limit() -> (i32, i32)241 fn exponent_limit() -> (i32, i32); 242 243 /// Get the number of digits that can be shifted from exponent to mantissa. mantissa_limit() -> i32244 fn mantissa_limit() -> i32; 245 246 // Re-exported methods from std. pow10(self, n: i32) -> Self247 fn pow10(self, n: i32) -> Self; from_bits(u: Self::Unsigned) -> Self248 fn from_bits(u: Self::Unsigned) -> Self; to_bits(self) -> Self::Unsigned249 fn to_bits(self) -> Self::Unsigned; is_sign_positive(self) -> bool250 fn is_sign_positive(self) -> bool; is_sign_negative(self) -> bool251 fn is_sign_negative(self) -> bool; 252 253 /// Returns true if the float is a denormal. 254 #[inline] is_denormal(self) -> bool255 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] is_special(self) -> bool261 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] is_inf(self) -> bool267 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] exponent(self) -> i32273 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] mantissa(self) -> Self::Unsigned285 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] next_positive(self) -> Self298 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] round_positive_even(self) -> Self305 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] exponent_limit() -> (i32, i32)333 fn exponent_limit() -> (i32, i32) { 334 (-10, 10) 335 } 336 337 #[inline] mantissa_limit() -> i32338 fn mantissa_limit() -> i32 { 339 7 340 } 341 342 #[inline] pow10(self, n: i32) -> f32343 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] from_bits(u: u32) -> f32358 fn from_bits(u: u32) -> f32 { 359 f32::from_bits(u) 360 } 361 362 #[inline] to_bits(self) -> u32363 fn to_bits(self) -> u32 { 364 f32::to_bits(self) 365 } 366 367 #[inline] is_sign_positive(self) -> bool368 fn is_sign_positive(self) -> bool { 369 f32::is_sign_positive(self) 370 } 371 372 #[inline] is_sign_negative(self) -> bool373 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] exponent_limit() -> (i32, i32)397 fn exponent_limit() -> (i32, i32) { 398 (-22, 22) 399 } 400 401 #[inline] mantissa_limit() -> i32402 fn mantissa_limit() -> i32 { 403 15 404 } 405 406 #[inline] pow10(self, n: i32) -> f64407 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] from_bits(u: u64) -> f64422 fn from_bits(u: u64) -> f64 { 423 f64::from_bits(u) 424 } 425 426 #[inline] to_bits(self) -> u64427 fn to_bits(self) -> u64 { 428 f64::to_bits(self) 429 } 430 431 #[inline] is_sign_positive(self) -> bool432 fn is_sign_positive(self) -> bool { 433 f64::is_sign_positive(self) 434 } 435 436 #[inline] is_sign_negative(self) -> bool437 fn is_sign_negative(self) -> bool { 438 f64::is_sign_negative(self) 439 } 440 } 441