summaryrefslogtreecommitdiffstats
path: root/vendor/minimal-lexical/tests/slow_tests.rs
blob: 2afea69e908a730871fe44cedfbb80237351eee8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
mod stackvec;

use minimal_lexical::bigint::Bigint;
use minimal_lexical::extended_float::ExtendedFloat;
use minimal_lexical::num::Float;
use minimal_lexical::number::Number;
use minimal_lexical::slow;
use stackvec::vec_from_u32;

fn b<F: Float>(float: F) -> (u64, i32) {
    let fp = slow::b(float);
    (fp.mant, fp.exp)
}

fn bh<F: Float>(float: F) -> (u64, i32) {
    let fp = slow::bh(float);
    (fp.mant, fp.exp)
}

#[test]
fn b_test() {
    assert_eq!(b(1e-45_f32), (1, -149));
    assert_eq!(b(5e-324_f64), (1, -1074));
    assert_eq!(b(1e-323_f64), (2, -1074));
    assert_eq!(b(2e-323_f64), (4, -1074));
    assert_eq!(b(3e-323_f64), (6, -1074));
    assert_eq!(b(4e-323_f64), (8, -1074));
    assert_eq!(b(5e-323_f64), (10, -1074));
    assert_eq!(b(6e-323_f64), (12, -1074));
    assert_eq!(b(7e-323_f64), (14, -1074));
    assert_eq!(b(8e-323_f64), (16, -1074));
    assert_eq!(b(9e-323_f64), (18, -1074));
    assert_eq!(b(1_f32), (8388608, -23));
    assert_eq!(b(1_f64), (4503599627370496, -52));
    assert_eq!(b(1e38_f32), (9860761, 103));
    assert_eq!(b(1e308_f64), (5010420900022432, 971));
}

#[test]
fn bh_test() {
    assert_eq!(bh(1e-45_f32), (3, -150));
    assert_eq!(bh(5e-324_f64), (3, -1075));
    assert_eq!(bh(1_f32), (16777217, -24));
    assert_eq!(bh(1_f64), (9007199254740993, -53));
    assert_eq!(bh(1e38_f32), (19721523, 102));
    assert_eq!(bh(1e308_f64), (10020841800044865, 970));
}

#[test]
fn slow_test() {
    // 5e-324, round-down.
    let integer = b"2";
    let fraction = b"4703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328124999";
    let num = Number {
        mantissa: 2470328229206232720,
        exponent: -342,
        many_digits: true,
    };
    let fp = ExtendedFloat {
        mant: 1 << 63,
        exp: -63,
    };
    let result = slow::slow::<f64, _, _>(num.clone(), fp, integer.iter(), fraction.iter());
    assert_eq!(result.mant, 0);
    assert_eq!(result.exp, 0);

    // 5e-324, round-up.
    let fraction = b"47032822920623272088284396434110686182529901307162382212792841250337753635104375932649918180817996189898282347722858865463328355177969898199387398005390939063150356595155702263922908583924491051844359318028499365361525003193704576782492193656236698636584807570015857692699037063119282795585513329278343384093519780155312465972635795746227664652728272200563740064854999770965994704540208281662262378573934507363390079677619305775067401763246736009689513405355374585166611342237666786041621596804619144672918403005300575308490487653917113865916462395249126236538818796362393732804238910186723484976682350898633885879256283027559956575244555072551893136908362547791869486679949683240497058210285131854513962138377228261454376934125320985913276672363281251";
    let result = slow::slow::<f64, _, _>(num.clone(), fp, integer.iter(), fraction.iter());
    assert_eq!(result.mant, 1);
    assert_eq!(result.exp, 0);

    // 8.98846567431158e+307
    let integer = b"8";
    let fraction = b"9884656743115805365666807213050294962762414131308158973971342756154045415486693752413698006024096935349884403114202125541629105369684531108613657287705365884742938136589844238179474556051429647415148697857438797685859063890851407391008830874765563025951597582513936655578157348020066364210154316532161708032";
    let num = Number {
        mantissa: 8988465674311580536,
        exponent: 289,
        many_digits: true,
    };
    let fp = ExtendedFloat {
        mant: 9223372036854776832,
        exp: 2035,
    };
    let result = slow::slow::<f64, _, _>(num.clone(), fp, integer.iter(), fraction.iter());
    assert_eq!(result.mant, 0);
    assert_eq!(result.exp, 2046);

    // 8.988465674311582e+307
    let fraction = b"98846567431158053656668072130502949627624141313081589739713427561540454154866937524136980060240969353498844031142021255416291053696845311086136572877053658847429381365898442381794745560514296474151486978574387976858590638908514073910088308747655630259515975825139366555781573480200663642101543165321617080321";
    let result = slow::slow::<f64, _, _>(num.clone(), fp, integer.iter(), fraction.iter());
    assert_eq!(result.mant, 1);
    assert_eq!(result.exp, 2046);
}

#[test]
fn positive_digit_comp_test() {
    // 8.98846567431158e+307
    let bigmant = Bigint {
        data: vec_from_u32(&[
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 1024, 2147483648,
        ]),
    };
    let exponent = 307 + 1 - 308;
    let result = slow::positive_digit_comp::<f64>(bigmant, exponent);
    assert_eq!(result.mant, 0);
    assert_eq!(result.exp, 2046);

    // 8.988465674311582e+307
    let bigmant = Bigint {
        data: vec_from_u32(&[
            1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 1024, 2147483648,
        ]),
    };
    let exponent = 307 + 1 - 308;
    let result = slow::positive_digit_comp::<f64>(bigmant, exponent);
    assert_eq!(result.mant, 1);
    assert_eq!(result.exp, 2046);
}

#[test]
fn negative_digit_comp_test() {
    // 5e-324, below halfway, round-down to 0.0.
    let bigmant = Bigint {
        data: vec_from_u32(&[
            1727738439, 330069557, 3509095598, 686205316, 156923684, 750687444, 2688855918,
            28211928, 1887482096, 3222998811, 913348873, 1652282845, 1600735541, 1664240266,
            84454144, 1487769792, 1855966778, 2832488299, 507030148, 1410055467, 2513359584,
            3453963205, 779237894, 3456088326, 3671009895, 3094451696, 1250165638, 2682979794,
            357925323, 1713890438, 3271046672, 3485897285, 3934710962, 1813530592, 199705026,
            976390839, 2805488572, 2194288220, 2094065006, 2592523639, 3798974617, 586957244,
            1409218821, 3442050171, 3789534764, 1380190380, 2055222457, 3535299831, 429482276,
            389342206, 133558576, 721875297, 3013586570, 540178306, 2389746866, 2313334501,
            422440635, 1288499129, 864978311, 842263325, 3016323856, 2282442263, 1440906063,
            3931458696, 3511314276, 1884879882, 946366824, 4260548261, 1073379659, 1732329252,
            3828972211, 1915607049, 3665440937, 1844358779, 3735281178, 2646335050, 1457460927,
            2940016422, 1051,
        ]),
    };
    let fp = ExtendedFloat {
        mant: 1 << 63,
        exp: -63,
    };
    let exponent = -324 + 1 - 755;
    let result = slow::negative_digit_comp::<f64>(bigmant, fp, exponent);
    assert_eq!(result.mant, 0);
    assert_eq!(result.exp, 0);

    // 5e-324, halfway, round-down to 0.0.
    let bigmant = Bigint {
        data: vec_from_u32(&[
            2084786877, 507136210, 2666388819, 3110242527, 3178432722, 541916566, 208847286,
            3092404665, 83491860, 2893735989, 3973758097, 2600107496, 147629623, 1754010897,
            4226332273, 2587058081, 942453804, 88731834, 1319061990, 173208747, 1982493283,
            3808794987, 3874839738, 1854586992, 3508364323, 2021729080, 1899625710, 2420749567,
            816401711, 3059730605, 1570934109, 3138812023, 1756281367, 3205859133, 2985201975,
            1014588672, 3799556578, 577719905, 4052248225, 3649019757, 398935965, 56421532,
            976366795, 1876047791, 3147705595, 4025764546, 1097271882, 1910500779, 2397021233,
            1340419138, 2753207595, 3067328524, 2210626776, 1280440432, 3940874757, 4172726578,
            1035509558, 1062145421, 1465448826, 2990139501, 1785427751, 2093931515, 4055890033,
            3388365687, 2245484242, 3609657408, 3527114516, 1013577862, 2389075196, 426934091,
            3237939346, 1071362463, 4070999470, 250952461, 2280067948, 1097862995, 2226250520,
            221983348, 1,
        ]),
    };
    let exponent = -324 + 1 - 752;
    let result = slow::negative_digit_comp::<f64>(bigmant, fp, exponent);
    assert_eq!(result.mant, 0);
    assert_eq!(result.exp, 0);

    // 5e-324, above halfway, round-up to 5e-324.
    let bigmant = Bigint {
        data: vec_from_u32(&[
            3667999587, 776394808, 894084415, 1037654204, 1719556155, 1124198371, 2088472861,
            859275578, 834918607, 3167556114, 1082875312, 231271193, 1476296236, 360239786,
            3608617070, 100777043, 834603454, 887318342, 305718012, 1732087473, 2645063646,
            3728211506, 93691724, 1366000745, 723904866, 3037421624, 1816387920, 2732659194,
            3869049819, 532534979, 2824439209, 1323349161, 382944493, 1993820262, 4082215981,
            1555952134, 3635827414, 1482231762, 1867776587, 2130459211, 3989359658, 564215320,
            1173733358, 1580608728, 1412284882, 1602939803, 2382784237, 1925138608, 2495375854,
            519289497, 1762272177, 608514174, 631431287, 4214469733, 754041908, 3072560125,
            1765160997, 2031519620, 1769586374, 4131591237, 674408332, 3759445970, 1904194670,
            3818885807, 980005947, 1736835717, 911406800, 1545844036, 2415915482, 4269340915,
            2314622388, 2123690045, 2055289038, 2509524619, 1325843000, 2388695363, 787668722,
            2219833485, 10,
        ]),
    };
    let exponent = -324 + 1 - 753;
    let result = slow::negative_digit_comp::<f64>(bigmant, fp, exponent);
    assert_eq!(result.mant, 1);
    assert_eq!(result.exp, 0);

    // 1e-323, below halfway, round-down to 5e-324.
    let bigmant = Bigint {
        data: vec_from_u32(&[
            888248023, 990208672, 1937352202, 2058615950, 470771052, 2252062332, 3771600458,
            84635785, 1367478992, 1079061842, 2740046621, 661881239, 507239328, 697753503,
            253362433, 168342080, 1272933039, 4202497602, 1521090445, 4230166401, 3245111456,
            1771955024, 2337713684, 1778330386, 2423095095, 693420498, 3750496916, 3753972086,
            1073775970, 846704018, 1223205425, 1867757265, 3214198296, 1145624482, 599115079,
            2929172517, 4121498420, 2287897365, 1987227723, 3482603622, 2806989260, 1760871734,
            4227656463, 1736215921, 2778669702, 4140571142, 1870700075, 2015964902, 1288446830,
            1168026618, 400675728, 2165625891, 450825118, 1620534920, 2874273302, 2645036208,
            1267321906, 3865497387, 2594934933, 2526789975, 459036976, 2552359495, 27750894,
            3204441497, 1944008238, 1359672352, 2839100473, 4191710191, 3220138979, 902020460,
            2896982042, 1451853853, 2406388220, 1238109043, 2615908943, 3644037856, 77415486,
            230114675, 3155,
        ]),
    };
    let fp = ExtendedFloat {
        mant: 1 << 63,
        exp: -62,
    };
    let exponent = -324 + 1 - 755;
    let result = slow::negative_digit_comp::<f64>(bigmant, fp, exponent);
    assert_eq!(result.mant, 1);
    assert_eq!(result.exp, 0);

    // 1e-323, halfway, round-up to 1e-323.
    let bigmant = Bigint {
        data: vec_from_u32(&[
            1959393335, 1521408631, 3704199161, 740792990, 945363576, 1625749700, 626541858,
            687279403, 250475582, 91273375, 3331339701, 3505355194, 442888870, 967065395,
            4089062228, 3466206949, 2827361413, 266195502, 3957185970, 519626241, 1652512553,
            2836450370, 3034584624, 1268793682, 1935158378, 1770219946, 1403909835, 2967281406,
            2449205134, 589257223, 417835033, 826501478, 973876807, 1027642808, 365671335,
            3043766018, 2808735142, 1733159717, 3566810083, 2357124681, 1196807897, 169264596,
            2929100385, 1333176077, 853182194, 3487359048, 3291815648, 1436535041, 2896096404,
            4021257415, 3964655489, 612050981, 2336913034, 3841321297, 3232689679, 3928245144,
            3106528676, 3186436263, 101379182, 380483912, 1061315959, 1986827250, 3577735508,
            1575162471, 2441485432, 2239037633, 1991408958, 3040733588, 2872258292, 1280802274,
            1123883446, 3214087391, 3623063818, 752857385, 2545236548, 3293588986, 2383784264,
            665950045, 3,
        ]),
    };
    let exponent = -324 + 1 - 752;
    let result = slow::negative_digit_comp::<f64>(bigmant, fp, exponent);
    assert_eq!(result.mant, 2);
    assert_eq!(result.exp, 0);

    // 1e-323, above halfway, round-up to 1e-323.
    let bigmant = Bigint {
        data: vec_from_u32(&[
            2414064167, 2329184426, 2682253245, 3112962612, 863701169, 3372595114, 1970451287,
            2577826735, 2504755821, 912733750, 3248625938, 693813579, 133921412, 1080719359,
            2235916618, 302331131, 2503810362, 2661955026, 917154036, 901295123, 3640223643,
            2594699927, 281075174, 4098002235, 2171714598, 522330280, 1154196466, 3903010287,
            3017214866, 1597604939, 4178350331, 3970047484, 1148833479, 1686493490, 3656713352,
            372889108, 2317547651, 151727992, 1308362466, 2096410338, 3378144383, 1692645962,
            3521200074, 446858888, 4236854647, 513852113, 2853385416, 1480448529, 3191160267,
            1557868492, 991849235, 1825542523, 1894293861, 4053474607, 2262125726, 627745783,
            1000515697, 1799591565, 1013791827, 3804839120, 2023224998, 2688403318, 1417616716,
            2866722830, 2940017843, 915539855, 2734220401, 342564812, 2952779151, 4218088154,
            2648899870, 2076102840, 1870899819, 3233606562, 3977529001, 2871118793, 2363006167,
            2364533159, 31,
        ]),
    };
    let exponent = -324 + 1 - 753;
    let result = slow::negative_digit_comp::<f64>(bigmant, fp, exponent);
    assert_eq!(result.mant, 2);
    assert_eq!(result.exp, 0);
}

#[test]
fn parse_mantissa_test() {
    let max_digits = f64::MAX_DIGITS;

    // Large number of digits.
    let integer = b"2";
    let fraction = b"4703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328124999";
    let (bigmant, count) = slow::parse_mantissa(integer.iter(), fraction.iter(), max_digits);
    let expected = vec_from_u32(&[
        1727738439, 330069557, 3509095598, 686205316, 156923684, 750687444, 2688855918, 28211928,
        1887482096, 3222998811, 913348873, 1652282845, 1600735541, 1664240266, 84454144,
        1487769792, 1855966778, 2832488299, 507030148, 1410055467, 2513359584, 3453963205,
        779237894, 3456088326, 3671009895, 3094451696, 1250165638, 2682979794, 357925323,
        1713890438, 3271046672, 3485897285, 3934710962, 1813530592, 199705026, 976390839,
        2805488572, 2194288220, 2094065006, 2592523639, 3798974617, 586957244, 1409218821,
        3442050171, 3789534764, 1380190380, 2055222457, 3535299831, 429482276, 389342206,
        133558576, 721875297, 3013586570, 540178306, 2389746866, 2313334501, 422440635, 1288499129,
        864978311, 842263325, 3016323856, 2282442263, 1440906063, 3931458696, 3511314276,
        1884879882, 946366824, 4260548261, 1073379659, 1732329252, 3828972211, 1915607049,
        3665440937, 1844358779, 3735281178, 2646335050, 1457460927, 2940016422, 1051,
    ]);
    assert_eq!(&*bigmant.data, &*expected);
    assert_eq!(count, 755);

    // Truncation.
    let integer = b"7";
    let fraction = b"4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375332669816033062329967789262837";
    let (bigmant, count) = slow::parse_mantissa(integer.iter(), fraction.iter(), max_digits);
    let expected = vec_from_u32(&[
        983641521, 2202462645, 4170685875, 1591772364, 529830014, 803977727, 126733331, 1695971390,
        4089590927, 1532849076, 2705586665, 4046282448, 4076195232, 3230469892, 3059053929,
        79035789, 744229654, 2026438108, 3570486781, 2818088662, 3485839733, 3653138023,
        2857937689, 602717004, 3689362390, 283607819, 1783392475, 2053068939, 1888214698,
        550023429, 296880187, 1046779059, 1285361259, 84614934, 1627922685, 2023868765, 1987523901,
        743493573, 3897769089, 2210613570, 2261081349, 3015057659, 3949711644, 3346092916,
        2433639051, 36411806, 1050442, 269209477, 2649742673, 1494221829, 2763524503, 2514491481,
        2325312415, 1741242814, 2479923579, 1098250122, 2416211509, 3612906464, 403420662,
        3663250314, 1993722098, 365907183, 4270226312, 3962131185, 432952495, 2963635838,
        2996289227, 3200289391, 2753231690, 2780286109, 884373163, 1418533204, 3382415762,
        499541562, 3369625401, 3421327641, 3526770155, 3109983188, 1157439767, 734593155,
    ]);
    assert_eq!(&*bigmant.data, &*expected);
    assert_eq!(count, max_digits + 1);

    // No fraction digits.
    let integer = b"74109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375332669816033062329967789262837";
    let fraction = b"";
    let (bigmant, count) = slow::parse_mantissa(integer.iter(), fraction.iter(), max_digits);
    assert_eq!(&*bigmant.data, &*expected);
    assert_eq!(count, max_digits + 1);

    // Multiple of step (check we add our temporary correctly).
    let integer = b"7410984687618698162648531893023320585475897039214871466383785237510132609053131277979497545424539885696948470431685765963899850655339096945981621940161728171894510697854671067917687257517734731555330779540854980960845750095811137303474765809687100959097544227100475730780971111893578483867565399878350301522805593404659373979179073872386829939581848166016912201945649993128979841136206248449867871357218035220901702390328579173252022052897402080290685402160661237554998340267130003581248647904138574340187552090159017259254714629617513415977493871857473787096164563890871811984127167305601704549300470526959016576377688490826798697257336652176556794107250876433756084600398490497214911746308553955635418864151316847843631308023759629577398300170898437533266981";
    let fraction = b"";
    let (bigmant, count) = slow::parse_mantissa(integer.iter(), fraction.iter(), max_digits);
    let expected = vec_from_u32(&[
        617018405, 396211401, 2130402383, 3812547827, 4263683770, 3918012496, 1787721490,
        2493014694, 435464626, 3720854431, 2928509507, 2677932436, 369049650, 3606588290,
        231237141, 2231172875, 3358152367, 95217925, 2777810007, 1016185079, 596681915, 2331711780,
        593487272, 4212730845, 339602972, 4097829793, 262427536, 4182115035, 3414687403,
        3711518952, 4168896929, 483727327, 1657080031, 2785588628, 1009114769, 482126749,
        485376744, 1123705337, 3225501941, 2939050108, 1338451005, 2104263947, 3425461126,
        1834224928, 4061025704, 792093815, 2707019125, 3610271203, 4254101529, 1026215278,
        4117890107, 1748110416, 2535111606, 80965120, 3823822115, 2354910057, 590658512,
        2682089507, 159300272, 1776569442, 3382166479, 3222978591, 540586210, 934713382,
        2014123057, 1455555790, 4119131465, 3685912982, 3019947291, 3437891678, 2660105801,
        2605860762, 394373515, 4177081532, 1616198650, 1580399082, 2017617452, 3327697130,
        315505357,
    ]);
    assert_eq!(&*bigmant.data, &*expected);
    assert_eq!(count, 760);
}