1 #![cfg(feature = "compact")]
2
3 mod bellerophon;
4
5 use bellerophon::{bellerophon_test, compute_float32, compute_float64};
6 use minimal_lexical::num::Float;
7
8 #[test]
halfway_round_down_test()9 fn halfway_round_down_test() {
10 // Halfway, round-down tests
11 bellerophon_test::<f64>(9007199254740992, 0, false, 0, 1076);
12 bellerophon_test::<f64>(
13 9007199254740993,
14 0,
15 false,
16 9223372036854776832,
17 1065 + f64::INVALID_FP,
18 );
19 bellerophon_test::<f64>(9007199254740994, 0, false, 1, 1076);
20
21 bellerophon_test::<f64>(18014398509481984, 0, false, 0, 1077);
22 bellerophon_test::<f64>(
23 18014398509481986,
24 0,
25 false,
26 9223372036854776832,
27 1066 + f64::INVALID_FP,
28 );
29 bellerophon_test::<f64>(18014398509481988, 0, false, 1, 1077);
30
31 bellerophon_test::<f64>(9223372036854775808, 0, false, 0, 1086);
32 bellerophon_test::<f64>(
33 9223372036854776832,
34 0,
35 false,
36 9223372036854776832,
37 1075 + f64::INVALID_FP,
38 );
39 bellerophon_test::<f64>(9223372036854777856, 0, false, 1, 1086);
40
41 // Add a 0 but say we're truncated.
42 bellerophon_test::<f64>(9007199254740992000, -3, true, 0, 1076);
43 bellerophon_test::<f64>(
44 9007199254740993000,
45 -3,
46 true,
47 9223372036854776832,
48 1065 + f64::INVALID_FP,
49 );
50 bellerophon_test::<f64>(9007199254740994000, -3, true, 1, 1076);
51 }
52
53 #[test]
halfway_round_up_test()54 fn halfway_round_up_test() {
55 // Halfway, round-up tests
56 bellerophon_test::<f64>(9007199254740994, 0, false, 1, 1076);
57 bellerophon_test::<f64>(
58 9007199254740995,
59 0,
60 false,
61 9223372036854778880,
62 1065 + f64::INVALID_FP,
63 );
64 bellerophon_test::<f64>(9007199254740996, 0, false, 2, 1076);
65
66 bellerophon_test::<f64>(18014398509481988, 0, false, 1, 1077);
67 bellerophon_test::<f64>(
68 18014398509481990,
69 0,
70 false,
71 9223372036854778880,
72 1066 + f64::INVALID_FP,
73 );
74 bellerophon_test::<f64>(18014398509481992, 0, false, 2, 1077);
75
76 bellerophon_test::<f64>(9223372036854777856, 0, false, 1, 1086);
77 bellerophon_test::<f64>(
78 9223372036854778880,
79 0,
80 false,
81 9223372036854778880,
82 1075 + f64::INVALID_FP,
83 );
84 bellerophon_test::<f64>(9223372036854779904, 0, false, 2, 1086);
85
86 // Add a 0 but say we're truncated.
87 bellerophon_test::<f64>(9007199254740994000, -3, true, 1, 1076);
88 bellerophon_test::<f64>(
89 9007199254740994990,
90 -3,
91 true,
92 9223372036854778869,
93 1065 + f64::INVALID_FP,
94 );
95 bellerophon_test::<f64>(
96 9007199254740995000,
97 -3,
98 true,
99 9223372036854778879,
100 1065 + f64::INVALID_FP,
101 );
102 bellerophon_test::<f64>(
103 9007199254740995010,
104 -3,
105 true,
106 9223372036854778890,
107 1065 + f64::INVALID_FP,
108 );
109 bellerophon_test::<f64>(9007199254740995050, -3, true, 2, 1076);
110 bellerophon_test::<f64>(9007199254740996000, -3, true, 2, 1076);
111 }
112
113 #[test]
extremes_test()114 fn extremes_test() {
115 // Need to check we get proper results with rounding for near-infinity
116 // and near-zero and/or denormal floats.
117 bellerophon_test::<f64>(5, -324, false, 1, 0);
118 bellerophon_test::<f64>(10, -324, false, 2, 0);
119 // This is very close to 2.4703282292062327206e-342.
120 bellerophon_test::<f64>(
121 2470328229206232720,
122 -342,
123 false,
124 18446744073709551608,
125 -64 + f64::INVALID_FP,
126 );
127 bellerophon_test::<f64>(2470328229206232721, -342, false, 9223372036854775808, -32831);
128 bellerophon_test::<f64>(2470328229206232725, -342, false, 9223372036854775824, -32831);
129 bellerophon_test::<f64>(2470328229206232726, -342, false, 1, 0);
130 bellerophon_test::<f64>(2470328229206232730, -342, false, 1, 0);
131 // Check very close to literal infinity.
132 // 17.976931348623155
133 // 1.797693134862315508561243283845062402343434371574593359244049e+308
134 // 1.797693134862315708145274237317043567980705675258449965989175e+308
135 bellerophon_test::<f64>(17976931348623155, 292, false, 4503599627370494, 2046);
136 bellerophon_test::<f64>(17976931348623156, 292, false, 4503599627370494, 2046);
137 bellerophon_test::<f64>(1797693134862315605, 290, false, 4503599627370494, 2046);
138 bellerophon_test::<f64>(1797693134862315607, 290, false, 4503599627370494, 2046);
139 bellerophon_test::<f64>(1797693134862315608, 290, false, 18446744073709548540, -30733);
140 bellerophon_test::<f64>(1797693134862315609, 290, false, 18446744073709548550, -30733);
141 bellerophon_test::<f64>(179769313486231561, 291, false, 4503599627370495, 2046);
142 bellerophon_test::<f64>(17976931348623157, 292, false, 4503599627370495, 2046);
143
144 // Check existing issues and underflow.
145 bellerophon_test::<f64>(2470328229206232726, -343, false, 0, 0);
146 bellerophon_test::<f64>(2470328229206232726, -342, false, 1, 0);
147 bellerophon_test::<f64>(1, -250, false, 1945308223406668, 192);
148 bellerophon_test::<f64>(1, -150, false, 2867420733609077, 524);
149 bellerophon_test::<f64>(1, -45, false, 1924152549665465, 873);
150 bellerophon_test::<f64>(1, -40, false, 400386103400348, 890);
151 bellerophon_test::<f64>(1, -20, false, 2142540351554083, 956);
152 bellerophon_test::<f64>(1, 0, false, 0, 1023);
153 bellerophon_test::<f64>(1, 20, false, 1599915997629504, 1089);
154 bellerophon_test::<f64>(1, 40, false, 3768206498159781, 1155);
155 bellerophon_test::<f64>(1, 150, false, 999684479948463, 1521);
156 bellerophon_test::<f64>(1, 250, false, 1786584717939204, 1853);
157 // Minimum positive normal float.
158 bellerophon_test::<f64>(22250738585072014, -324, false, 0, 1);
159 // Maximum positive subnormal float.
160 bellerophon_test::<f64>(2225073858507201, -323, false, 4503599627370495, 0);
161 // Next highest subnormal float.
162 bellerophon_test::<f64>(22250738585072004, -324, false, 4503599627370494, 0);
163 bellerophon_test::<f64>(22250738585072006, -324, false, 4503599627370494, 0);
164 bellerophon_test::<f64>(22250738585072007, -324, false, 4503599627370495, 0);
165 bellerophon_test::<f64>(222507385850720062, -325, false, 4503599627370494, 0);
166 bellerophon_test::<f64>(222507385850720063, -325, false, 4503599627370494, 0);
167 bellerophon_test::<f64>(222507385850720064, -325, false, 4503599627370494, 0);
168 bellerophon_test::<f64>(2225073858507200641, -326, false, 18446744073709545462, -32779);
169 bellerophon_test::<f64>(2225073858507200642, -326, false, 18446744073709545472, -32779);
170 bellerophon_test::<f64>(222507385850720065, -325, false, 4503599627370495, 0);
171 }
172
173 #[test]
compute_float_f32_test()174 fn compute_float_f32_test() {
175 // These test near-halfway cases for single-precision floats.
176 assert_eq!(compute_float32(0, 16777216), (151, 0));
177 assert_eq!(compute_float32(0, 16777217), (111 + f32::INVALID_FP, 9223372586610589696));
178 assert_eq!(compute_float32(0, 16777218), (151, 1));
179 assert_eq!(compute_float32(0, 16777219), (111 + f32::INVALID_FP, 9223373686122217472));
180 assert_eq!(compute_float32(0, 16777220), (151, 2));
181
182 // These are examples of the above tests, with
183 // digits from the exponent shifted to the mantissa.
184 assert_eq!(compute_float32(-10, 167772160000000000), (151, 0));
185 assert_eq!(
186 compute_float32(-10, 167772170000000000),
187 (111 + f32::INVALID_FP, 9223372586610589696)
188 );
189 assert_eq!(compute_float32(-10, 167772180000000000), (151, 1));
190 // Let's check the lines to see if anything is different in table...
191 assert_eq!(
192 compute_float32(-10, 167772190000000000),
193 (111 + f32::INVALID_FP, 9223373686122217472)
194 );
195 assert_eq!(compute_float32(-10, 167772200000000000), (151, 2));
196 }
197
198 #[test]
compute_float_f64_test()199 fn compute_float_f64_test() {
200 // These test near-halfway cases for double-precision floats.
201 assert_eq!(compute_float64(0, 9007199254740992), (1076, 0));
202 assert_eq!(compute_float64(0, 9007199254740993), (1065 + f64::INVALID_FP, 9223372036854776832));
203 assert_eq!(compute_float64(0, 9007199254740994), (1076, 1));
204 assert_eq!(compute_float64(0, 9007199254740995), (1065 + f64::INVALID_FP, 9223372036854778880));
205 assert_eq!(compute_float64(0, 9007199254740996), (1076, 2));
206 assert_eq!(compute_float64(0, 18014398509481984), (1077, 0));
207 assert_eq!(
208 compute_float64(0, 18014398509481986),
209 (1066 + f64::INVALID_FP, 9223372036854776832)
210 );
211 assert_eq!(compute_float64(0, 18014398509481988), (1077, 1));
212 assert_eq!(
213 compute_float64(0, 18014398509481990),
214 (1066 + f64::INVALID_FP, 9223372036854778880)
215 );
216 assert_eq!(compute_float64(0, 18014398509481992), (1077, 2));
217
218 // These are examples of the above tests, with
219 // digits from the exponent shifted to the mantissa.
220 assert_eq!(compute_float64(-3, 9007199254740992000), (1076, 0));
221 assert_eq!(
222 compute_float64(-3, 9007199254740993000),
223 (1065 + f64::INVALID_FP, 9223372036854776832)
224 );
225 assert_eq!(compute_float64(-3, 9007199254740994000), (1076, 1));
226 assert_eq!(
227 compute_float64(-3, 9007199254740995000),
228 (1065 + f64::INVALID_FP, 9223372036854778879)
229 );
230 assert_eq!(compute_float64(-3, 9007199254740996000), (1076, 2));
231 }
232