|  | 
| 8 | 8 | // option. This file may not be copied, modified, or distributed | 
| 9 | 9 | // except according to those terms. | 
| 10 | 10 | 
 | 
|  | 11 | +use std::f32; | 
| 11 | 12 | use std::f64; | 
| 12 |  | -use std::mem; | 
| 13 | 13 | use core::num::diy_float::Fp; | 
| 14 | 14 | use core::num::dec2flt::rawfp::{fp_to_float, prev_float, next_float, round_normal}; | 
|  | 15 | +use core::num::dec2flt::rawfp::RawFloat; | 
| 15 | 16 | 
 | 
| 16 | 17 | fn integer_decode(f: f64) -> (u64, i16, i8) { | 
| 17 |  | -    let bits: u64 = unsafe { mem::transmute(f) }; | 
| 18 |  | -    let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 }; | 
| 19 |  | -    let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16; | 
| 20 |  | -    let mantissa = if exponent == 0 { | 
| 21 |  | -        (bits & 0xfffffffffffff) << 1 | 
| 22 |  | -    } else { | 
| 23 |  | -        (bits & 0xfffffffffffff) | 0x10000000000000 | 
| 24 |  | -    }; | 
| 25 |  | -    // Exponent bias + mantissa shift | 
| 26 |  | -    exponent -= 1023 + 52; | 
| 27 |  | -    (mantissa, exponent, sign) | 
|  | 18 | +    RawFloat::integer_decode(f) | 
| 28 | 19 | } | 
| 29 | 20 | 
 | 
| 30 | 21 | #[test] | 
| @@ -152,3 +143,35 @@ fn next_float_monotonic() { | 
| 152 | 143 |     } | 
| 153 | 144 |     assert!(x > 0.5); | 
| 154 | 145 | } | 
|  | 146 | + | 
|  | 147 | +#[test] | 
|  | 148 | +fn test_f32_integer_decode() { | 
|  | 149 | +    assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1)); | 
|  | 150 | +    assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1)); | 
|  | 151 | +    assert_eq!(2f32.powf(100.0).integer_decode(), (8388608, 77, 1)); | 
|  | 152 | +    assert_eq!(0f32.integer_decode(), (0, -150, 1)); | 
|  | 153 | +    assert_eq!((-0f32).integer_decode(), (0, -150, -1)); | 
|  | 154 | +    assert_eq!(f32::INFINITY.integer_decode(), (8388608, 105, 1)); | 
|  | 155 | +    assert_eq!(f32::NEG_INFINITY.integer_decode(), (8388608, 105, -1)); | 
|  | 156 | + | 
|  | 157 | +    // Ignore the "sign" (quiet / signalling flag) of NAN. | 
|  | 158 | +    // It can vary between runtime operations and LLVM folding. | 
|  | 159 | +    let (nan_m, nan_e, _nan_s) = f32::NAN.integer_decode(); | 
|  | 160 | +    assert_eq!((nan_m, nan_e), (12582912, 105)); | 
|  | 161 | +} | 
|  | 162 | + | 
|  | 163 | +#[test] | 
|  | 164 | +fn test_f64_integer_decode() { | 
|  | 165 | +    assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1)); | 
|  | 166 | +    assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1)); | 
|  | 167 | +    assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496, 48, 1)); | 
|  | 168 | +    assert_eq!(0f64.integer_decode(), (0, -1075, 1)); | 
|  | 169 | +    assert_eq!((-0f64).integer_decode(), (0, -1075, -1)); | 
|  | 170 | +    assert_eq!(f64::INFINITY.integer_decode(), (4503599627370496, 972, 1)); | 
|  | 171 | +    assert_eq!(f64::NEG_INFINITY.integer_decode(), (4503599627370496, 972, -1)); | 
|  | 172 | + | 
|  | 173 | +    // Ignore the "sign" (quiet / signalling flag) of NAN. | 
|  | 174 | +    // It can vary between runtime operations and LLVM folding. | 
|  | 175 | +    let (nan_m, nan_e, _nan_s) = f64::NAN.integer_decode(); | 
|  | 176 | +    assert_eq!((nan_m, nan_e), (6755399441055744, 972)); | 
|  | 177 | +} | 
0 commit comments