|
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