1#![cfg(feature = "compact")]
2
3mod bellerophon;
4
5use bellerophon::{bellerophon_test, compute_float32, compute_float64};
6use minimal_lexical::num::Float;
7
8#[test]
9fn 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]
54fn 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]
114fn 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]
174fn 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]
199fn 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