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