1 use core
::num
::dec2flt
::rawfp
::RawFloat
;
2 use core
::num
::dec2flt
::rawfp
::{fp_to_float, next_float, prev_float, round_normal}
;
3 use core
::num
::diy_float
::Fp
;
7 fn integer_decode(f
: f64) -> (u64, i16, i8) {
8 RawFloat
::integer_decode(f
)
12 fn fp_to_float_half_to_even() {
13 fn is_normalized(sig
: u64) -> bool
{
14 // intentionally written without {min,max}_sig() as a sanity check
15 sig
>> 52 == 1 && sig
>> 53 == 0
18 fn conv(sig
: u64) -> u64 {
19 // The significands are perfectly in range, so the exponent should not matter
20 let (m1
, e1
, _
) = integer_decode(fp_to_float
::<f64>(Fp { f: sig, e: 0 }
));
21 assert_eq
!(e1
, 0 + 64 - 53);
22 let (m2
, e2
, _
) = integer_decode(fp_to_float
::<f64>(Fp { f: sig, e: 55 }
));
23 assert_eq
!(e2
, 55 + 64 - 53);
25 let (m3
, e3
, _
) = integer_decode(fp_to_float
::<f64>(Fp { f: sig, e: -78 }
));
26 assert_eq
!(e3
, -78 + 64 - 53);
31 let odd
= 0x1F_EDCB_A012_345F;
33 assert
!(is_normalized(odd
));
34 assert
!(is_normalized(even
));
35 assert_eq
!(conv(odd
<< 11), odd
);
36 assert_eq
!(conv(even
<< 11), even
);
37 assert_eq
!(conv(odd
<< 11 | 1 << 10), odd
+ 1);
38 assert_eq
!(conv(even
<< 11 | 1 << 10), even
);
39 assert_eq
!(conv(even
<< 11 | 1 << 10 | 1), even
+ 1);
40 assert_eq
!(conv(odd
<< 11 | 1 << 9), odd
);
41 assert_eq
!(conv(even
<< 11 | 1 << 9), even
);
42 assert_eq
!(conv(odd
<< 11 | 0x7FF), odd
+ 1);
43 assert_eq
!(conv(even
<< 11 | 0x7FF), even
+ 1);
44 assert_eq
!(conv(odd
<< 11 | 0x3FF), odd
);
45 assert_eq
!(conv(even
<< 11 | 0x3FF), even
);
49 fn integers_to_f64() {
50 assert_eq
!(fp_to_float
::<f64>(Fp { f: 1, e: 0 }
), 1.0);
51 assert_eq
!(fp_to_float
::<f64>(Fp { f: 42, e: 7 }
), (42 << 7) as f64);
52 assert_eq
!(fp_to_float
::<f64>(Fp { f: 1 << 20, e: 30 }
), (1u64 << 50) as f64);
53 assert_eq
!(fp_to_float
::<f64>(Fp { f: 4, e: -3 }
), 0.5);
56 const SOME_FLOATS
: [f64; 9] = [
69 fn human_f64_roundtrip() {
70 for &x
in &SOME_FLOATS
{
71 let (f
, e
, _
) = integer_decode(x
);
72 let fp
= Fp { f: f, e: e }
;
73 assert_eq
!(fp_to_float
::<f64>(fp
), x
);
78 fn rounding_overflow() {
79 let x
= Fp { f: 0xFF_FF_FF_FF_FF_FF_FF_00u64, e: 42 }
;
80 let rounded
= round_normal
::<f64>(x
);
81 let adjusted_k
= x
.e
+ 64 - 53;
82 assert_eq
!(rounded
.sig
, 1 << 52);
83 assert_eq
!(rounded
.k
, adjusted_k
+ 1);
86 #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
88 fn prev_float_monotonic() {
91 let x1
= prev_float(x
);
93 assert
!(x
- x1
< 1e
-15);
98 const MIN_SUBNORMAL
: f64 = 5e
-324;
101 fn next_float_zero() {
102 let tiny
= next_float(0.0);
103 assert_eq
!(tiny
, MIN_SUBNORMAL
);
104 assert
!(tiny
!= 0.0);
108 fn next_float_subnormal() {
109 let second
= next_float(MIN_SUBNORMAL
);
110 // For subnormals, MIN_SUBNORMAL is the ULP
111 assert
!(second
!= MIN_SUBNORMAL
);
112 assert
!(second
> 0.0);
113 assert_eq
!(second
- MIN_SUBNORMAL
, MIN_SUBNORMAL
);
117 fn next_float_inf() {
118 assert_eq
!(next_float(f64::MAX
), f64::INFINITY
);
119 assert_eq
!(next_float(f64::INFINITY
), f64::INFINITY
);
122 #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
124 fn next_prev_identity() {
125 for &x
in &SOME_FLOATS
{
126 assert_eq
!(prev_float(next_float(x
)), x
);
127 assert_eq
!(prev_float(prev_float(next_float(next_float(x
)))), x
);
128 assert_eq
!(next_float(prev_float(x
)), x
);
129 assert_eq
!(next_float(next_float(prev_float(prev_float(x
)))), x
);
133 #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
135 fn next_float_monotonic() {
136 let mut x
= 0.49999999999999;
139 let x1
= next_float(x
);
141 assert
!(x1
- x
< 1e
-15, "next_float_monotonic: delta = {:?}", x1
- x
);
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));
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));
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));
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));