1 //! These tests are adapted from the Rust core library's unittests.
2
3 #![cfg(not(feature = "compact"))]
4
5 use minimal_lexical::lemire;
6 use minimal_lexical::num::Float;
7
compute_error32(q: i32, w: u64) -> (i32, u64)8 fn compute_error32(q: i32, w: u64) -> (i32, u64) {
9 let fp = lemire::compute_error::<f32>(q, w);
10 (fp.exp, fp.mant)
11 }
12
compute_error64(q: i32, w: u64) -> (i32, u64)13 fn compute_error64(q: i32, w: u64) -> (i32, u64) {
14 let fp = lemire::compute_error::<f64>(q, w);
15 (fp.exp, fp.mant)
16 }
17
compute_error_scaled32(q: i32, w: u64, lz: i32) -> (i32, u64)18 fn compute_error_scaled32(q: i32, w: u64, lz: i32) -> (i32, u64) {
19 let fp = lemire::compute_error_scaled::<f32>(q, w, lz);
20 (fp.exp, fp.mant)
21 }
22
compute_error_scaled64(q: i32, w: u64, lz: i32) -> (i32, u64)23 fn compute_error_scaled64(q: i32, w: u64, lz: i32) -> (i32, u64) {
24 let fp = lemire::compute_error_scaled::<f64>(q, w, lz);
25 (fp.exp, fp.mant)
26 }
27
compute_float32(q: i32, w: u64) -> (i32, u64)28 fn compute_float32(q: i32, w: u64) -> (i32, u64) {
29 let fp = lemire::compute_float::<f32>(q, w);
30 (fp.exp, fp.mant)
31 }
32
compute_float64(q: i32, w: u64) -> (i32, u64)33 fn compute_float64(q: i32, w: u64) -> (i32, u64) {
34 let fp = lemire::compute_float::<f64>(q, w);
35 (fp.exp, fp.mant)
36 }
37
38 #[test]
compute_error32_test()39 fn compute_error32_test() {
40 // These test near-halfway cases for single-precision floats.
41 assert_eq!(compute_error32(0, 16777216), (111 + f32::INVALID_FP, 9223372036854775808));
42 assert_eq!(compute_error32(0, 16777217), (111 + f32::INVALID_FP, 9223372586610589696));
43 assert_eq!(compute_error32(0, 16777218), (111 + f32::INVALID_FP, 9223373136366403584));
44 assert_eq!(compute_error32(0, 16777219), (111 + f32::INVALID_FP, 9223373686122217472));
45 assert_eq!(compute_error32(0, 16777220), (111 + f32::INVALID_FP, 9223374235878031360));
46
47 // These are examples of the above tests, with
48 // digits from the exponent shifted to the mantissa.
49 assert_eq!(
50 compute_error32(-10, 167772160000000000),
51 (111 + f32::INVALID_FP, 9223372036854775808)
52 );
53 assert_eq!(
54 compute_error32(-10, 167772170000000000),
55 (111 + f32::INVALID_FP, 9223372586610589696)
56 );
57 assert_eq!(
58 compute_error32(-10, 167772180000000000),
59 (111 + f32::INVALID_FP, 9223373136366403584)
60 );
61 // Let's check the lines to see if anything is different in table...
62 assert_eq!(
63 compute_error32(-10, 167772190000000000),
64 (111 + f32::INVALID_FP, 9223373686122217472)
65 );
66 assert_eq!(
67 compute_error32(-10, 167772200000000000),
68 (111 + f32::INVALID_FP, 9223374235878031360)
69 );
70 }
71
72 #[test]
compute_error64_test()73 fn compute_error64_test() {
74 // These test near-halfway cases for double-precision floats.
75 assert_eq!(compute_error64(0, 9007199254740992), (1065 + f64::INVALID_FP, 9223372036854775808));
76 assert_eq!(compute_error64(0, 9007199254740993), (1065 + f64::INVALID_FP, 9223372036854776832));
77 assert_eq!(compute_error64(0, 9007199254740994), (1065 + f64::INVALID_FP, 9223372036854777856));
78 assert_eq!(compute_error64(0, 9007199254740995), (1065 + f64::INVALID_FP, 9223372036854778880));
79 assert_eq!(compute_error64(0, 9007199254740996), (1065 + f64::INVALID_FP, 9223372036854779904));
80 assert_eq!(
81 compute_error64(0, 18014398509481984),
82 (1066 + f64::INVALID_FP, 9223372036854775808)
83 );
84 assert_eq!(
85 compute_error64(0, 18014398509481986),
86 (1066 + f64::INVALID_FP, 9223372036854776832)
87 );
88 assert_eq!(
89 compute_error64(0, 18014398509481988),
90 (1066 + f64::INVALID_FP, 9223372036854777856)
91 );
92 assert_eq!(
93 compute_error64(0, 18014398509481990),
94 (1066 + f64::INVALID_FP, 9223372036854778880)
95 );
96 assert_eq!(
97 compute_error64(0, 18014398509481992),
98 (1066 + f64::INVALID_FP, 9223372036854779904)
99 );
100
101 // Test a much closer set of examples.
102 assert_eq!(
103 compute_error64(0, 9007199254740991),
104 (1064 + f64::INVALID_FP, 18446744073709549568)
105 );
106 assert_eq!(
107 compute_error64(0, 9223372036854776831),
108 (1075 + f64::INVALID_FP, 9223372036854776830)
109 );
110 assert_eq!(
111 compute_error64(0, 9223372036854776832),
112 (1075 + f64::INVALID_FP, 9223372036854776832)
113 );
114 assert_eq!(
115 compute_error64(0, 9223372036854776833),
116 (1075 + f64::INVALID_FP, 9223372036854776832)
117 );
118 assert_eq!(
119 compute_error64(-42, 9123456727292927),
120 (925 + f64::INVALID_FP, 13021432563531497894)
121 );
122 assert_eq!(
123 compute_error64(-43, 91234567272929275),
124 (925 + f64::INVALID_FP, 13021432563531498606)
125 );
126 assert_eq!(
127 compute_error64(-42, 9123456727292928),
128 (925 + f64::INVALID_FP, 13021432563531499320)
129 );
130
131 // These are examples of the above tests, with
132 // digits from the exponent shifted to the mantissa.
133 assert_eq!(
134 compute_error64(-3, 9007199254740992000),
135 (1065 + f64::INVALID_FP, 9223372036854775808)
136 );
137 assert_eq!(
138 compute_error64(-3, 9007199254740993000),
139 (1065 + f64::INVALID_FP, 9223372036854776832)
140 );
141 assert_eq!(
142 compute_error64(-3, 9007199254740994000),
143 (1065 + f64::INVALID_FP, 9223372036854777856)
144 );
145 assert_eq!(
146 compute_error64(-3, 9007199254740995000),
147 (1065 + f64::INVALID_FP, 9223372036854778880)
148 );
149 assert_eq!(
150 compute_error64(-3, 9007199254740996000),
151 (1065 + f64::INVALID_FP, 9223372036854779904)
152 );
153
154 // Test from errors in atof.
155 assert_eq!(
156 compute_error64(-18, 1000000178813934326),
157 (1012 + f64::INVALID_FP, 9223373686122217470)
158 );
159
160 // Check edge-cases from previous errors.
161 assert_eq!(
162 compute_error64(-342, 2470328229206232720),
163 (-64 + f64::INVALID_FP, 18446744073709551608)
164 );
165 }
166
167 #[test]
compute_error_scaled32_test()168 fn compute_error_scaled32_test() {
169 // These are the same examples above, just using pre-computed scaled values.
170
171 // These test near-halfway cases for single-precision floats.
172 assert_eq!(
173 compute_error_scaled32(0, 4611686018427387904, 39),
174 (111 + f32::INVALID_FP, 9223372036854775808)
175 );
176 assert_eq!(
177 compute_error_scaled32(0, 4611686293305294848, 39),
178 (111 + f32::INVALID_FP, 9223372586610589696)
179 );
180 assert_eq!(
181 compute_error_scaled32(0, 4611686568183201792, 39),
182 (111 + f32::INVALID_FP, 9223373136366403584)
183 );
184 assert_eq!(
185 compute_error_scaled32(0, 4611686843061108736, 39),
186 (111 + f32::INVALID_FP, 9223373686122217472)
187 );
188 assert_eq!(
189 compute_error_scaled32(0, 4611687117939015680, 39),
190 (111 + f32::INVALID_FP, 9223374235878031360)
191 );
192
193 assert_eq!(
194 compute_error_scaled32(-10, 9223372036854775808, 6),
195 (111 + f32::INVALID_FP, 9223372036854775808)
196 );
197 assert_eq!(
198 compute_error_scaled32(-10, 9223372586610589696, 6),
199 (111 + f32::INVALID_FP, 9223372586610589696)
200 );
201 assert_eq!(
202 compute_error_scaled32(-10, 9223373136366403584, 6),
203 (111 + f32::INVALID_FP, 9223373136366403584)
204 );
205 assert_eq!(
206 compute_error_scaled32(-10, 9223373686122217472, 6),
207 (111 + f32::INVALID_FP, 9223373686122217472)
208 );
209 assert_eq!(
210 compute_error_scaled32(-10, 9223374235878031360, 6),
211 (111 + f32::INVALID_FP, 9223374235878031360)
212 );
213 }
214
215 #[test]
compute_error_scaled64_test()216 fn compute_error_scaled64_test() {
217 // These are the same examples above, just using pre-computed scaled values.
218
219 // These test near-halfway cases for double-precision floats.
220 assert_eq!(
221 compute_error_scaled64(0, 4611686018427387904, 10),
222 (1065 + f64::INVALID_FP, 9223372036854775808)
223 );
224 assert_eq!(
225 compute_error_scaled64(0, 4611686018427388416, 10),
226 (1065 + f64::INVALID_FP, 9223372036854776832)
227 );
228 assert_eq!(
229 compute_error_scaled64(0, 4611686018427388928, 10),
230 (1065 + f64::INVALID_FP, 9223372036854777856)
231 );
232 assert_eq!(
233 compute_error_scaled64(0, 4611686018427389440, 10),
234 (1065 + f64::INVALID_FP, 9223372036854778880)
235 );
236 assert_eq!(
237 compute_error_scaled64(0, 4611686018427389952, 10),
238 (1065 + f64::INVALID_FP, 9223372036854779904)
239 );
240 assert_eq!(
241 compute_error_scaled64(0, 4611686018427387904, 9),
242 (1066 + f64::INVALID_FP, 9223372036854775808)
243 );
244 assert_eq!(
245 compute_error_scaled64(0, 4611686018427388416, 9),
246 (1066 + f64::INVALID_FP, 9223372036854776832)
247 );
248 assert_eq!(
249 compute_error_scaled64(0, 4611686018427388928, 9),
250 (1066 + f64::INVALID_FP, 9223372036854777856)
251 );
252 assert_eq!(
253 compute_error_scaled64(0, 4611686018427389440, 9),
254 (1066 + f64::INVALID_FP, 9223372036854778880)
255 );
256 assert_eq!(
257 compute_error_scaled64(0, 4611686018427389952, 9),
258 (1066 + f64::INVALID_FP, 9223372036854779904)
259 );
260
261 // Test a much closer set of examples.
262 assert_eq!(
263 compute_error_scaled64(0, 9223372036854774784, 11),
264 (1064 + f64::INVALID_FP, 18446744073709549568)
265 );
266 assert_eq!(
267 compute_error_scaled64(0, 4611686018427388415, 0),
268 (1075 + f64::INVALID_FP, 9223372036854776830)
269 );
270 assert_eq!(
271 compute_error_scaled64(0, 4611686018427388416, 0),
272 (1075 + f64::INVALID_FP, 9223372036854776832)
273 );
274 assert_eq!(
275 compute_error_scaled64(0, 4611686018427388416, 0),
276 (1075 + f64::INVALID_FP, 9223372036854776832)
277 );
278 assert_eq!(
279 compute_error_scaled64(-42, 6510716281765748947, 10),
280 (925 + f64::INVALID_FP, 13021432563531497894)
281 );
282 assert_eq!(
283 compute_error_scaled64(-43, 6510716281765749303, 7),
284 (925 + f64::INVALID_FP, 13021432563531498606)
285 );
286 assert_eq!(
287 compute_error_scaled64(-42, 6510716281765749660, 10),
288 (925 + f64::INVALID_FP, 13021432563531499320)
289 );
290
291 // These are examples of the above tests, with
292 // digits from the exponent shifted to the mantissa.
293 assert_eq!(
294 compute_error_scaled64(-3, 9223372036854775808, 1),
295 (1065 + f64::INVALID_FP, 9223372036854775808)
296 );
297 assert_eq!(
298 compute_error_scaled64(-3, 9223372036854776832, 1),
299 (1065 + f64::INVALID_FP, 9223372036854776832)
300 );
301 assert_eq!(
302 compute_error_scaled64(-3, 9223372036854777856, 1),
303 (1065 + f64::INVALID_FP, 9223372036854777856)
304 );
305 assert_eq!(
306 compute_error_scaled64(-3, 9223372036854778880, 1),
307 (1065 + f64::INVALID_FP, 9223372036854778880)
308 );
309 assert_eq!(
310 compute_error_scaled64(-3, 9223372036854779904, 1),
311 (1065 + f64::INVALID_FP, 9223372036854779904)
312 );
313
314 // Test from errors in atof.
315 assert_eq!(
316 compute_error_scaled64(-18, 9223373686122217470, 4),
317 (1012 + f64::INVALID_FP, 9223373686122217470)
318 );
319
320 // Check edge-cases from previous errors.
321 assert_eq!(
322 compute_error_scaled64(-342, 9223372036854775804, 2),
323 (-64 + f64::INVALID_FP, 18446744073709551608)
324 );
325 }
326
327 #[test]
compute_float_f32_rounding()328 fn compute_float_f32_rounding() {
329 // These test near-halfway cases for single-precision floats.
330 assert_eq!(compute_float32(0, 16777216), (151, 0));
331 assert_eq!(compute_float32(0, 16777217), (151, 0));
332 assert_eq!(compute_float32(0, 16777218), (151, 1));
333 assert_eq!(compute_float32(0, 16777219), (151, 2));
334 assert_eq!(compute_float32(0, 16777220), (151, 2));
335
336 // These are examples of the above tests, with
337 // digits from the exponent shifted to the mantissa.
338 assert_eq!(compute_float32(-10, 167772160000000000), (151, 0));
339 assert_eq!(compute_float32(-10, 167772170000000000), (151, 0));
340 assert_eq!(compute_float32(-10, 167772180000000000), (151, 1));
341 // Let's check the lines to see if anything is different in table...
342 assert_eq!(compute_float32(-10, 167772190000000000), (151, 2));
343 assert_eq!(compute_float32(-10, 167772200000000000), (151, 2));
344 }
345
346 #[test]
compute_float_f64_rounding()347 fn compute_float_f64_rounding() {
348 // Also need to check halfway cases **inside** that exponent range.
349
350 // These test near-halfway cases for double-precision floats.
351 assert_eq!(compute_float64(0, 9007199254740992), (1076, 0));
352 assert_eq!(compute_float64(0, 9007199254740993), (1076, 0));
353 assert_eq!(compute_float64(0, 9007199254740994), (1076, 1));
354 assert_eq!(compute_float64(0, 9007199254740995), (1076, 2));
355 assert_eq!(compute_float64(0, 9007199254740996), (1076, 2));
356 assert_eq!(compute_float64(0, 18014398509481984), (1077, 0));
357 assert_eq!(compute_float64(0, 18014398509481986), (1077, 0));
358 assert_eq!(compute_float64(0, 18014398509481988), (1077, 1));
359 assert_eq!(compute_float64(0, 18014398509481990), (1077, 2));
360 assert_eq!(compute_float64(0, 18014398509481992), (1077, 2));
361
362 // Test a much closer set of examples.
363 assert_eq!(compute_float64(0, 9007199254740991), (1075, 4503599627370495));
364 assert_eq!(compute_float64(0, 9223372036854776831), (1086, 0));
365 assert_eq!(compute_float64(0, 9223372036854776832), (1086, 0));
366 assert_eq!(compute_float64(0, 9223372036854776833), (1086, 1));
367 assert_eq!(compute_float64(-42, 9123456727292927), (936, 1854521741541368));
368 assert_eq!(compute_float64(-43, 91234567272929275), (936, 1854521741541369));
369 assert_eq!(compute_float64(-42, 9123456727292928), (936, 1854521741541369));
370
371 // These are examples of the above tests, with
372 // digits from the exponent shifted to the mantissa.
373 assert_eq!(compute_float64(-3, 9007199254740992000), (1076, 0));
374 assert_eq!(compute_float64(-3, 9007199254740993000), (1076, 0));
375 assert_eq!(compute_float64(-3, 9007199254740994000), (1076, 1));
376 assert_eq!(compute_float64(-3, 9007199254740995000), (1076, 2));
377 assert_eq!(compute_float64(-3, 9007199254740996000), (1076, 2));
378 }
379