]> git.lizzy.rs Git - rust.git/blob - src/libcore/tests/num/dec2flt/rawfp.rs
Rollup merge of #42252 - stjepang:clarify-alignof-docs, r=nikomatsakis
[rust.git] / src / libcore / tests / num / dec2flt / rawfp.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use std::f32;
12 use std::f64;
13 use core::num::diy_float::Fp;
14 use core::num::dec2flt::rawfp::{fp_to_float, prev_float, next_float, round_normal};
15 use core::num::dec2flt::rawfp::RawFloat;
16
17 fn integer_decode(f: f64) -> (u64, i16, i8) {
18     RawFloat::integer_decode(f)
19 }
20
21 #[test]
22 fn fp_to_float_half_to_even() {
23     fn is_normalized(sig: u64) -> bool {
24         // intentionally written without {min,max}_sig() as a sanity check
25         sig >> 52 == 1 && sig >> 53 == 0
26     }
27
28     fn conv(sig: u64) -> u64 {
29         // The significands are perfectly in range, so the exponent should not matter
30         let (m1, e1, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: 0 }));
31         assert_eq!(e1, 0 + 64 - 53);
32         let (m2, e2, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: 55 }));
33         assert_eq!(e2, 55 + 64 - 53);
34         assert_eq!(m2, m1);
35         let (m3, e3, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: -78 }));
36         assert_eq!(e3, -78 + 64 - 53);
37         assert_eq!(m3, m2);
38         m3
39     }
40
41     let odd = 0x1F_EDCB_A012_345F;
42     let even = odd - 1;
43     assert!(is_normalized(odd));
44     assert!(is_normalized(even));
45     assert_eq!(conv(odd << 11), odd);
46     assert_eq!(conv(even << 11), even);
47     assert_eq!(conv(odd << 11 | 1 << 10), odd + 1);
48     assert_eq!(conv(even << 11 | 1 << 10), even);
49     assert_eq!(conv(even << 11 | 1 << 10 | 1), even + 1);
50     assert_eq!(conv(odd << 11 | 1 << 9), odd);
51     assert_eq!(conv(even << 11 | 1 << 9), even);
52     assert_eq!(conv(odd << 11 | 0x7FF), odd + 1);
53     assert_eq!(conv(even << 11 | 0x7FF), even + 1);
54     assert_eq!(conv(odd << 11 | 0x3FF), odd);
55     assert_eq!(conv(even << 11 | 0x3FF), even);
56 }
57
58 #[test]
59 fn integers_to_f64() {
60     assert_eq!(fp_to_float::<f64>(Fp { f: 1, e: 0 }), 1.0);
61     assert_eq!(fp_to_float::<f64>(Fp { f: 42, e: 7 }), (42 << 7) as f64);
62     assert_eq!(fp_to_float::<f64>(Fp { f: 1 << 20, e: 30 }), (1u64 << 50) as f64);
63     assert_eq!(fp_to_float::<f64>(Fp { f: 4, e: -3 }), 0.5);
64 }
65
66 const SOME_FLOATS: [f64; 9] =
67     [0.1f64, 33.568, 42.1e-5, 777.0e9, 1.1111, 0.347997,
68      9843579834.35892, 12456.0e-150, 54389573.0e-150];
69
70
71 #[test]
72 fn human_f64_roundtrip() {
73     for &x in &SOME_FLOATS {
74         let (f, e, _) = integer_decode(x);
75         let fp = Fp { f: f, e: e};
76         assert_eq!(fp_to_float::<f64>(fp), x);
77     }
78 }
79
80 #[test]
81 fn rounding_overflow() {
82     let x = Fp { f: 0xFF_FF_FF_FF_FF_FF_FF_00u64, e: 42 };
83     let rounded = round_normal::<f64>(x);
84     let adjusted_k = x.e + 64 - 53;
85     assert_eq!(rounded.sig, 1 << 52);
86     assert_eq!(rounded.k, adjusted_k + 1);
87 }
88
89 #[test]
90 fn prev_float_monotonic() {
91     let mut x = 1.0;
92     for _ in 0..100 {
93         let x1 = prev_float(x);
94         assert!(x1 < x);
95         assert!(x - x1 < 1e-15);
96         x = x1;
97     }
98 }
99
100 const MIN_SUBNORMAL: f64 = 5e-324;
101
102 #[test]
103 fn next_float_zero() {
104     let tiny = next_float(0.0);
105     assert_eq!(tiny, MIN_SUBNORMAL);
106     assert!(tiny != 0.0);
107 }
108
109 #[test]
110 fn next_float_subnormal() {
111     let second = next_float(MIN_SUBNORMAL);
112     // For subnormals, MIN_SUBNORMAL is the ULP
113     assert!(second != MIN_SUBNORMAL);
114     assert!(second > 0.0);
115     assert_eq!(second - MIN_SUBNORMAL, MIN_SUBNORMAL);
116 }
117
118 #[test]
119 fn next_float_inf() {
120     assert_eq!(next_float(f64::MAX), f64::INFINITY);
121     assert_eq!(next_float(f64::INFINITY), f64::INFINITY);
122 }
123
124 #[test]
125 fn next_prev_identity() {
126     for &x in &SOME_FLOATS {
127         assert_eq!(prev_float(next_float(x)), x);
128         assert_eq!(prev_float(prev_float(next_float(next_float(x)))), x);
129         assert_eq!(next_float(prev_float(x)), x);
130         assert_eq!(next_float(next_float(prev_float(prev_float(x)))), x);
131     }
132 }
133
134 #[test]
135 fn next_float_monotonic() {
136     let mut x = 0.49999999999999;
137     assert!(x < 0.5);
138     for _ in 0..200 {
139         let x1 = next_float(x);
140         assert!(x1 > x);
141         assert!(x1 - x < 1e-15, "next_float_monotonic: delta = {:?}", x1 - x);
142         x = x1;
143     }
144     assert!(x > 0.5);
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 }