|
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