forked from Yaffle/BigDecimal
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtests.js
More file actions
461 lines (400 loc) · 36.2 KB
/
tests.js
File metadata and controls
461 lines (400 loc) · 36.2 KB
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
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
import BigDecimal2 from './BigDecimalByDecimal.js.js';
import {BigDecimal, BigFloat} from './BigDecimal.js';
console.time();
console.assert(BigDecimal.toNumber(BigDecimal.BigDecimal(100)) === 100);
console.assert(BigDecimal.toNumber(BigDecimal.unaryMinus(BigDecimal.BigDecimal(100))) === -100);
console.assert(BigDecimal.toNumber(BigDecimal.add(BigDecimal.BigDecimal(100), BigDecimal.BigDecimal(2))) === 102);
console.assert(BigDecimal.toNumber(BigDecimal.subtract(BigDecimal.BigDecimal(100), BigDecimal.BigDecimal(2))) === 98);
console.assert(BigDecimal.toNumber(BigDecimal.multiply(BigDecimal.BigDecimal(100), BigDecimal.BigDecimal(2))) === 200);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(100), BigDecimal.BigDecimal(2), { maximumSignificantDigits: 1, roundingMode: 'floor' })) === 50);
console.assert(BigDecimal.lessThan(BigDecimal.BigDecimal(2), BigDecimal.BigDecimal(3)) === true);
console.assert(BigDecimal.lessThan(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(3)) === false);
console.assert(BigDecimal.lessThan(BigDecimal.BigDecimal(1), BigDecimal.BigDecimal(0)) === false);
console.assert(BigDecimal.lessThan(BigDecimal.BigDecimal(-1), BigDecimal.BigDecimal(0)) === true);
console.assert(BigDecimal.lessThan(BigDecimal.BigDecimal(0), BigDecimal.BigDecimal(0)) === false);
console.assert(BigDecimal.lessThan(BigDecimal.BigDecimal(0), BigDecimal.BigDecimal(1)) === true);
console.assert(BigDecimal.lessThan(BigDecimal.add(BigDecimal.divide(BigDecimal.BigDecimal(1), BigDecimal.BigDecimal(100), { maximumSignificantDigits: 1, roundingMode: 'floor' }), BigDecimal.BigDecimal(1)), BigDecimal.BigDecimal(2)));
console.assert(BigDecimal.lessThan(BigDecimal.add(BigDecimal.divide(BigDecimal.BigDecimal(1), BigDecimal.BigDecimal(100), { maximumFractionDigits: 2, roundingMode: 'floor' }), BigDecimal.BigDecimal(1)), BigDecimal.BigDecimal(2)));
console.assert(BigDecimal.lessThan(BigDecimal.BigDecimal(String(1/3)), BigDecimal.BigDecimal('0')) === false);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(2), { maximumSignificantDigits: 1, roundingMode: 'floor' })) === 1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 1, roundingMode: 'floor' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(2), { maximumSignificantDigits: 1, roundingMode: 'floor' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 1, roundingMode: 'floor' })) === 1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(2), { maximumFractionDigits: 0, roundingMode: 'floor' })) === 1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(-2), { maximumFractionDigits: 0, roundingMode: 'floor' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(2), { maximumFractionDigits: 0, roundingMode: 'floor' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(-2), { maximumFractionDigits: 0, roundingMode: 'floor' })) === 1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(2), { maximumSignificantDigits: 1, roundingMode: 'ceil' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 1, roundingMode: 'ceil' })) === -1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(2), { maximumSignificantDigits: 1, roundingMode: 'ceil' })) === -1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 1, roundingMode: 'ceil' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(2), { maximumFractionDigits: 0, roundingMode: 'ceil' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(-2), { maximumFractionDigits: 0, roundingMode: 'ceil' })) === -1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(2), { maximumFractionDigits: 0, roundingMode: 'ceil' })) === -1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(-2), { maximumFractionDigits: 0, roundingMode: 'ceil' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(2), { maximumSignificantDigits: 1, roundingMode: 'half-even' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 1, roundingMode: 'half-even' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(2), { maximumSignificantDigits: 1, roundingMode: 'half-even' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 1, roundingMode: 'half-even' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(2), { maximumFractionDigits: 0, roundingMode: 'half-even' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(-2), { maximumFractionDigits: 0, roundingMode: 'half-even' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(2), { maximumFractionDigits: 0, roundingMode: 'half-even' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(-2), { maximumFractionDigits: 0, roundingMode: 'half-even' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(5), BigDecimal.BigDecimal(2), { maximumSignificantDigits: 1, roundingMode: 'half-even' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(5), BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 1, roundingMode: 'half-even' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-5), BigDecimal.BigDecimal(2), { maximumSignificantDigits: 1, roundingMode: 'half-even' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-5), BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 1, roundingMode: 'half-even' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(5), BigDecimal.BigDecimal(2), { maximumFractionDigits: 0, roundingMode: 'half-even' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(5), BigDecimal.BigDecimal(-2), { maximumFractionDigits: 0, roundingMode: 'half-even' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-5), BigDecimal.BigDecimal(2), { maximumFractionDigits: 0, roundingMode: 'half-even' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-5), BigDecimal.BigDecimal(-2), { maximumFractionDigits: 0, roundingMode: 'half-even' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(2), { maximumSignificantDigits: 1, roundingMode: 'half-up' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 1, roundingMode: 'half-up' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(2), { maximumSignificantDigits: 1, roundingMode: 'half-up' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 1, roundingMode: 'half-up' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(2), { maximumFractionDigits: 0, roundingMode: 'half-up' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(-2), { maximumFractionDigits: 0, roundingMode: 'half-up' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(2), { maximumFractionDigits: 0, roundingMode: 'half-up' })) === -2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(-2), { maximumFractionDigits: 0, roundingMode: 'half-up' })) === 2);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(2), { maximumSignificantDigits: 1, roundingMode: 'half-down' })) === 1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 1, roundingMode: 'half-down' })) === -1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(2), { maximumSignificantDigits: 1, roundingMode: 'half-down' })) === -1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 1, roundingMode: 'half-down' })) === 1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(2), { maximumFractionDigits: 0, roundingMode: 'half-down' })) === 1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(3), BigDecimal.BigDecimal(-2), { maximumFractionDigits: 0, roundingMode: 'half-down' })) === -1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(2), { maximumFractionDigits: 0, roundingMode: 'half-down' })) === -1);
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(-3), BigDecimal.BigDecimal(-2), { maximumFractionDigits: 0, roundingMode: 'half-down' })) === 1);
// double rounding
console.assert(BigDecimal.toNumber(BigDecimal.divide(BigDecimal.BigDecimal(699), BigDecimal.BigDecimal(200), { maximumSignificantDigits: 1, roundingMode: 'half-even' })) === 3);
// bugs (thanks to https://github.com/MikeMcl/bignumber.js/issues/256):
console.assert(BigDecimal.add(BigDecimal.BigDecimal('2e-3'), BigDecimal.BigDecimal('-2e+1'), { maximumSignificantDigits: 1, roundingMode: 'floor' }).toString() === '-20');
console.assert(BigDecimal.add(BigDecimal.BigDecimal('4e-5'), BigDecimal.BigDecimal('-6e+4'), { maximumSignificantDigits: 1, roundingMode: 'ceil' }).toString() === '-50000');
console.assert(BigDecimal.add(BigDecimal.BigDecimal('-2e-7'), BigDecimal.BigDecimal('5e+0'), { maximumSignificantDigits: 3, roundingMode: 'ceil' }).toString() === '5');
console.assert(BigDecimal.add(BigDecimal.BigDecimal('1e+8'), BigDecimal.BigDecimal('-1e-8'), { maximumSignificantDigits: 1, roundingMode: 'floor' }).toString() === '90000000');
console.assert(BigDecimal.add(BigDecimal.BigDecimal('-1e+6'), BigDecimal.BigDecimal('-8e+8'), { maximumSignificantDigits: 3, roundingMode: 'floor' }).toString() === '-801000000');
console.assert(BigDecimal.add(BigDecimal.BigDecimal('-842e+671'), BigDecimal.BigDecimal('149e+37'), { maximumSignificantDigits: 367, roundingMode: 'ceil' }).toString() === '-8.419999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999e+673');
console.assert(BigDecimal.divide(BigDecimal.BigDecimal('-2e+1'), BigDecimal.BigDecimal('-3e+0'), { maximumSignificantDigits: 2, roundingMode: 'floor' }).toString() === '6.6');
console.assert(BigDecimal.divide(BigDecimal.BigDecimal('-3e-2'), BigDecimal.BigDecimal('-2e-3'), { maximumSignificantDigits: 2, roundingMode: 'floor' }).toString() === '15');
console.assert(BigDecimal.divide(BigDecimal.BigDecimal('-800e+447'), BigDecimal.BigDecimal('4e-697'), { maximumSignificantDigits: 1, roundingMode: 'ceil' }).toString() === '-2e+1146');
console.assert(BigDecimal.divide(BigDecimal.BigDecimal('1e-2'), BigDecimal.BigDecimal('-2e+1'), { maximumFractionDigits: 1, roundingMode: 'half-even' }).toString() === '0');
console.assert(BigDecimal.divide(BigDecimal.BigDecimal('-11e-1'), BigDecimal.BigDecimal('-3e-14'), { maximumSignificantDigits: 1, roundingMode: 'half-even' }).toString() === '40000000000000');
console.assert(BigDecimal.divide(BigDecimal.BigDecimal('6e+7'), BigDecimal.BigDecimal('-7e-2'), { maximumSignificantDigits: 1, roundingMode: 'half-even' }).toString() === '-900000000');
console.assert(BigDecimal.divide(BigDecimal.BigDecimal('6e-6'), BigDecimal.BigDecimal('-9e+3'), { maximumSignificantDigits: 1, roundingMode: 'floor' }).toString() === '-7e-10');
// special cases
console.assert(BigDecimal.add(BigDecimal.BigDecimal('1e+9000000000000000'), BigDecimal.BigDecimal('1e+0'), { maximumSignificantDigits: 1, roundingMode: 'floor' }).toString() === '1e+9000000000000000');
//console.assert(BigDecimal.add(BigDecimal.BigDecimal('1e+10000000000000001'), BigDecimal.BigDecimal('1e-1'), { maximumFractionDigits: 0, roundingMode: 'floor' }).toString() === '1e+10000000000000001');
// console.time(); exponentiate(BigDecimal.BigDecimal(10), 1000000n); console.timeEnd();
//console.assert(BigDecimal.divide(BigDecimal.BigDecimal(1), BigDecimal.BigDecimal(10), {maximumSignificantDigits: 1e9, roundingMode: 'half-even'}).toString() === '0.1'); // performance
//console.assert(BigDecimal.divide(BigDecimal.BigDecimal(1), BigDecimal.BigDecimal(10), {maximumFractionDigits: 1e15}).toString(), '?'); // performance
//console.assert(BigDecimal.exp(BigDecimal.BigDecimal('1e+100'), { maximumSignificantDigits: 1, roundingMode: 'half-even' }).toString() === '2e+4342944819032518276511289189166050822943970058036665661144537831658646492088707747292249493384317483');
//console.assert(BigDecimal.exp(BigDecimal.BigDecimal('-1e+100'), { maximumSignificantDigits: 1, roundingMode: 'half-even' }).toString() === '7e-4342944819032518276511289189166050822943970058036665661144537831658646492088707747292249493384317484');
console.assert(BigDecimal.exp(BigDecimal.BigDecimal(0), {maximumFractionDigits: 0, roundingMode: 'half-even'}));
// fromString
//console.assert(BigDecimal.BigDecimal(' +1.2e+3 ').toString() === '120');
console.assert(BigDecimal.BigDecimal('1e+2').toString() === '100');
// toString
console.assert(BigDecimal.BigDecimal(1).toString() === '1');
console.assert(BigDecimal.BigDecimal('999999999999999999999').toString() === '999999999999999999999'); // 1e+21 - 1
console.assert(BigDecimal.BigDecimal('1000000000000000000000').toString() === '1e+21');
console.assert(BigDecimal.BigDecimal('1.2345').toString() === '1.2345');
console.assert(BigDecimal.BigDecimal('0.000001').toString() === '0.000001');
console.assert(BigDecimal.BigDecimal('0.00000012').toString() === '1.2e-7');
console.assert(BigDecimal.BigDecimal(-1).toString() === '-1');
console.assert(BigDecimal.BigDecimal('1e+21').toString() === '1e+21');
// toExponential
//console.assert(BigDecimal.BigDecimal(' +1.2e+3 ').toExponential() === '1.2e+3');
console.assert(BigDecimal.BigDecimal('1.5').toExponential(0) === '2e+0');
console.assert(BigDecimal.BigDecimal('2.5').toExponential(0) === '3e+0');
console.assert(BigDecimal.BigDecimal('-1.5').toExponential(0) === '-2e+0');
console.assert(BigDecimal.BigDecimal('-2.5').toExponential(0) === '-3e+0');
console.assert(BigDecimal.BigDecimal('1.5').toExponential(1) === '1.5e+0');
console.assert(BigDecimal.BigDecimal('1234567890').toExponential(3) === '1.235e+9');
// toPrecision
console.assert(BigDecimal.BigDecimal('-1.5').toPrecision(1) === '-2');
console.assert(BigDecimal.BigDecimal('-1e-7').toPrecision(2) === '-1.0e-7');
console.assert(BigDecimal.BigDecimal('-1e-6').toPrecision(2) === '-0.0000010');
console.assert(BigDecimal.BigDecimal('-1.5').toPrecision(3) === '-1.50');
console.assert(BigDecimal.BigDecimal('95e-8').toPrecision(1) === '0.000001');
console.assert(BigDecimal.BigDecimal('94e-8').toPrecision(1) === '9e-7');
// toFixed
console.assert(BigDecimal.BigDecimal('-1.5').toFixed(0) === '-2');
console.assert(BigDecimal.BigDecimal('-1.5').toFixed(1) === '-1.5');
console.assert(BigDecimal.BigDecimal('-1.5').toFixed(2) === '-1.50');
console.assert(BigDecimal.BigDecimal('1.5e+1').toFixed(2) === '15.00');
console.assert(BigDecimal.BigDecimal('5e-1').toFixed(0) === '1');
console.assert(BigDecimal.BigDecimal('0').toFixed(0) === '0');
console.assert(BigDecimal.BigDecimal('999999999999999999999.4').toFixed(0) === '999999999999999999999');
//console.assert(BigDecimal.BigDecimal('999999999999999999999.5').toFixed(0) === '1e+21'); //TODO: not specified (!)
//console.assert(BigDecimal.BigDecimal('1e+21').toFixed(0) === '1e+21');
console.assert(BigDecimal.BigDecimal('-1e-100').toFixed(10) === '-0.0000000000');
// BigDecimal.log
console.assert(BigDecimal.log(BigDecimal.BigDecimal(10), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '2.302585092994046');
console.assert(BigDecimal.log(BigDecimal.BigDecimal(2), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '0.6931471805599453');
console.assert(BigDecimal.log(BigDecimal.BigDecimal(1e10), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '23.02585092994046');
console.assert(BigDecimal.log(BigDecimal.BigDecimal('0.01'), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '-4.605170185988091');
console.assert(BigDecimal.log(BigDecimal.BigDecimal('0.1'), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '-2.302585092994046');
console.assert(BigDecimal.log(BigDecimal.BigDecimal(1), { maximumSignificantDigits: 16, roundingMode: 'ceil' }).toString() === '0');
console.assert(BigDecimal.log(BigDecimal.BigDecimal(1), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '0');
console.assert(BigDecimal.log(BigDecimal.BigDecimal(1), { maximumSignificantDigits: 16, roundingMode: 'floor' }).toString() === '0');
console.assert(BigDecimal.log(BigDecimal.BigDecimal('2.718281830905498'), { maximumSignificantDigits: 16, roundingMode: 'floor' }).toString() === '1.000000000899999');
console.assert(BigDecimal.log(BigDecimal.BigDecimal('2.718281830905498'), { maximumSignificantDigits: 11, roundingMode: 'floor' }).toString() === '1.0000000008');
console.assert(BigDecimal.log(BigDecimal.BigDecimal('2.718281830905498'), { maximumSignificantDigits: 12, roundingMode: 'ceil' }).toString() === '1.0000000009');
console.assert(BigDecimal.log(BigDecimal.BigDecimal('2.718281830905498'), { maximumSignificantDigits: 1, roundingMode: 'floor' }).toString() === '1');
console.assert(BigDecimal.log(BigDecimal.BigDecimal('2.718281830905498'), { maximumSignificantDigits: 1, roundingMode: 'ceil' }).toString() === '2');
console.assert(BigDecimal.log(BigDecimal.BigDecimal('1e-10'), { maximumSignificantDigits: 8, roundingMode: 'half-even' }).toString() === '-23.025851');
// BigDecimal.exp
console.assert(BigDecimal.exp(BigDecimal.BigDecimal(1), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '2.718281828459045');
console.assert(BigDecimal.exp(BigDecimal.BigDecimal(700), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '1.014232054735005e+304');
console.assert(BigDecimal.exp(BigDecimal.BigDecimal(-10), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '0.00004539992976248485');
console.assert(BigDecimal.exp(BigDecimal.BigDecimal(0), { maximumSignificantDigits: 16, roundingMode: 'ceil' }).toString() === '1');
console.assert(BigDecimal.exp(BigDecimal.BigDecimal(0), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '1');
console.assert(BigDecimal.exp(BigDecimal.BigDecimal(0), { maximumSignificantDigits: 16, roundingMode: 'floor' }).toString() === '1');
console.assert(BigDecimal.exp(BigDecimal.BigDecimal(-100), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '3.720075976020836e-44');
console.assert(BigDecimal.exp(BigDecimal.BigDecimal(10), { maximumSignificantDigits: 11, roundingMode: 'half-even' }).toString() === '22026.465795');
// BigDecimal.sin
console.assert(BigDecimal.sin(BigDecimal.BigDecimal(1), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '0.8414709848078965');
console.assert(BigDecimal.sin(BigDecimal.BigDecimal(3), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '0.1411200080598672');
console.assert(BigDecimal.sin(BigDecimal.BigDecimal(4), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '-0.7568024953079283');
console.assert(BigDecimal.sin(BigDecimal.BigDecimal('-25.132741228718345'), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '9.07701147066236e-16');
console.assert(BigDecimal.sin(BigDecimal.BigDecimal(0), { maximumSignificantDigits: 16, roundingMode: 'ceil' }).toString() === '0');
console.assert(BigDecimal.sin(BigDecimal.BigDecimal(0), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '0');
console.assert(BigDecimal.sin(BigDecimal.BigDecimal(0), { maximumSignificantDigits: 16, roundingMode: 'floor' }).toString() === '0');
console.assert(BigDecimal.equal(BigDecimal.sin(BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 16, roundingMode: 'floor' }), BigDecimal.unaryMinus(BigDecimal.sin(BigDecimal.BigDecimal(2), { maximumSignificantDigits: 16, roundingMode: 'ceil' }))));
//console.assert(BigDecimal.sin(BigDecimal.BigDecimal('25e-10000'), { maximumSignificantDigits: 1, roundingMode: 'half-even' }).toString() === '?');
// BigDecimal.cos
console.assert(BigDecimal.cos(BigDecimal.BigDecimal(1), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '0.5403023058681397');
console.assert(BigDecimal.cos(BigDecimal.BigDecimal(3), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '-0.9899924966004455');
console.assert(BigDecimal.cos(BigDecimal.BigDecimal(4), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '-0.6536436208636119');
console.assert(BigDecimal.cos(BigDecimal.BigDecimal(0), { maximumSignificantDigits: 16, roundingMode: 'ceil' }).toString() === '1');
console.assert(BigDecimal.cos(BigDecimal.BigDecimal(0), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '1');
console.assert(BigDecimal.cos(BigDecimal.BigDecimal(0), { maximumSignificantDigits: 16, roundingMode: 'floor' }).toString() === '1');
console.assert(BigDecimal.cos(BigDecimal.BigDecimal('8e+9'), { maximumSignificantDigits: 9, roundingMode: 'floor' }).toString() === '-0.0930906136'); // bug
console.assert(BigDecimal.cos(BigDecimal.BigDecimal('-10e-9'), {maximumSignificantDigits: 1, roundingMode: 'floor'}).toString() === '0.9');
console.assert(BigDecimal.cos(BigDecimal.BigDecimal('0.7854188942630302e+1'), {maximumSignificantDigits: 11, roundingMode: "half-even"}).toString() === '-0.00020730865433');
// BigDecimal.atan
console.assert(BigDecimal.multiply(BigDecimal.BigDecimal(4), BigDecimal.atan(BigDecimal.BigDecimal(1), { maximumSignificantDigits: 16, roundingMode: 'half-even' })).toString() === '3.1415926535897932');
console.assert(BigDecimal.multiply(BigDecimal.BigDecimal(6), BigDecimal.atan(BigDecimal.BigDecimal('0.5773502691896258'), { maximumSignificantDigits: 16, roundingMode: 'half-even' })).toString() === '3.1415926535897934');
console.assert(BigDecimal.multiply(BigDecimal.BigDecimal(3), BigDecimal.atan(BigDecimal.BigDecimal('1.7320508075688772'), { maximumSignificantDigits: 16, roundingMode: 'half-even' })).toString() === '3.141592653589794');
console.assert(BigDecimal.atan(BigDecimal.BigDecimal(100), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '1.560796660108231');
console.assert(BigDecimal.atan(BigDecimal.BigDecimal(0), { maximumSignificantDigits: 16, roundingMode: 'ceil' }).toString() === '0');
console.assert(BigDecimal.atan(BigDecimal.BigDecimal(0), { maximumSignificantDigits: 16, roundingMode: 'half-even' }).toString() === '0');
console.assert(BigDecimal.atan(BigDecimal.BigDecimal(0), { maximumSignificantDigits: 16, roundingMode: 'floor' }).toString() === '0');
console.assert(BigDecimal.equal(BigDecimal.atan(BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 16, roundingMode: 'half-even' }), BigDecimal.unaryMinus(BigDecimal.atan(BigDecimal.BigDecimal(2), { maximumSignificantDigits: 16, roundingMode: 'half-even' }))));
console.assert(BigDecimal.equal(BigDecimal.atan(BigDecimal.BigDecimal(-2), { maximumSignificantDigits: 16, roundingMode: 'floor' }), BigDecimal.unaryMinus(BigDecimal.atan(BigDecimal.BigDecimal(2), { maximumSignificantDigits: 16, roundingMode: 'ceil' }))));
console.assert(BigDecimal.atan(BigDecimal.BigDecimal('1.2013940941022994e+0'), { maximumSignificantDigits: 131, roundingMode: 'floor'}).toString() === '0.87662900911742523254158833425786381859637058696571583555234526689495460168293167698711440831010322876710017353790080996006194244976'); // bug
// BigDecimal.sqrt
console.assert(BigDecimal.sqrt(BigDecimal.BigDecimal(100), {maximumFractionDigits: 0, roundingMode: 'floor'}).toString() === '10');
console.assert(BigDecimal.sqrt(BigDecimal.BigDecimal(100), {maximumFractionDigits: 0, roundingMode: 'ceil'}).toString() === '10');
console.assert(BigDecimal.sqrt(BigDecimal.BigDecimal('0.0022543340705052373e+1'), {maximumSignificantDigits: 133, roundingMode: 'floor'}).toString() === '0.1501443995127769426052976079792471072949865532195559797216663259395716567795895845959219116376275197595509976588342401869302170077707');
console.assert(BigDecimal.sqrt(BigDecimal.BigDecimal('0.8064902266570342e+6'), {maximumSignificantDigits: 137, roundingMode: 'ceil'}).toString() === '898.04800910476618015029976392760697926908695002996368102408741467418735302842706678658172375120578579550953111677275701668340441136770143');
// BigDecimal.cbrt
console.assert(BigDecimal.cbrt(BigDecimal.BigDecimal(1000), {maximumFractionDigits: 0, roundingMode: 'floor'}).toString() === '10');
console.assert(BigDecimal.cbrt(BigDecimal.BigDecimal(1000), {maximumFractionDigits: 0, roundingMode: 'ceil'}).toString() === '10');
console.assert(BigDecimal.cbrt(BigDecimal.BigDecimal(-1000), {maximumFractionDigits: 0, roundingMode: 'floor'}).toString() === '-10');
console.assert(BigDecimal.cbrt(BigDecimal.BigDecimal(-1000), {maximumFractionDigits: 0, roundingMode: 'ceil'}).toString() === '-10');
console.assert(BigDecimal.cbrt(BigDecimal.BigDecimal('-0.10580501816456955e-1'), {maximumSignificantDigits: 5, roundingMode: 'ceil'}).toString() === '-0.21953');
//BigDecimal2
// random tests:
console.time('testing agains decimal.js');
for (var c = 0; c < 10000; c += 1) {
var aValue = ((-1 + 2 * Math.random()) + 'e+' + (Math.floor(Math.random() * 20) - 10)).replace(/\+\-/g, '-');
var bValue = ((-1 + 2 * Math.random()) + 'e+' + (Math.floor(Math.random() * 20) - 10)).replace(/\+\-/g, '-');
var operations = 'add subtract multiply divide log exp sin cos atan sqrt cbrt'.split(' ');
var operation = operations[Math.floor(Math.random() * operations.length)];
//var roundingType = Math.random() < 0.5 ? 'maximumSignificantDigits' : 'maximumFractionDigits';
var roundingType = 'maximumSignificantDigits';
var roundingModes = 'ceil floor half-even half-up half-down'.split(' ');
var roundingMode = roundingModes[Math.floor(Math.random() * roundingModes.length)];
var decimalDigits = Math.floor(Math.random() * 200);
var rounding = roundingType === 'maximumSignificantDigits' ? {
maximumSignificantDigits: Math.max(1, decimalDigits),
roundingMode: roundingMode
} : roundingType === 'maximumFractionDigits' ? {
maximumFractionDigits: Math.max(0, decimalDigits),
roundingMode: roundingMode
} : null;
var isZero = function (s) {
return s.startsWith('0') && s.startsWith('0.');
};
if ((operation !== 'divide' || !isZero(bValue)) &&
(operation !== 'log' || !isZero(aValue) && !aValue.startsWith('-')) &&
(operation !== 'sqrt' || !aValue.startsWith('-'))) {
var calc = function (BigDecimal) {
if (/^(log|exp|sin|cos|atan|sqrt|cbrt)$/.test(operation)) {
return BigDecimal[operation](BigDecimal.BigDecimal(aValue), rounding);
}
return BigDecimal[operation](BigDecimal.BigDecimal(aValue), BigDecimal.BigDecimal(bValue), rounding);
};
var cc = calc(BigDecimal);
var expected = calc(BigDecimal2);
if (cc.exponent > 9000000000000000n) {
cc = 'Infinity';
}
if (cc.exponent < -9000000000000000n) {
cc = '0';
}
if (cc.toString() !== expected.toString()) {
console.log(cc.toString(), expected.toString(), aValue, bValue, operation, rounding);
throw new Error(c);
}
}
}
console.timeEnd('testing agains decimal.js');
function random(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function randomNumber() {
var significand = 1 + Math.random() * 0.5;
var exponent = random(-1022, 1023);
var sign = Math.random() < 0.5 ? -1 : +1;
var value = sign * significand * Math.pow(2, exponent);
return Math.sign(value) * Math.max(Math.min(Math.abs(value), Number.MAX_VALUE), 2**-1022);
}
function bigdecimalFromNumber(number) {
var exponent = Math.floor(Math.log2(Math.abs(number)));
if (Math.abs(number) < 2**exponent) {
exponent -= 1;
}
const sign = BigDecimal.BigDecimal(Math.sign(number));
const decimal = BigDecimal.divide(BigDecimal.BigDecimal(Math.abs(number) / 2**exponent * (Number.MAX_SAFE_INTEGER + 1) / 2), BigDecimal.BigDecimal((Number.MAX_SAFE_INTEGER + 1) / 2));
const scale = exponent >= 0 ? BigDecimal.BigDecimal(2**exponent) : BigDecimal.divide(BigDecimal.BigDecimal(1), BigDecimal.BigDecimal(2**-exponent));
return BigDecimal.multiply(sign, BigDecimal.multiply(decimal, scale));
}
console.time('testing Number#toLocaleString');
for (var c = 0; c < 10000; c += 1) {
var number = randomNumber();
//var bigdecimal = bigdecimalFromNumber(number);
// https://github.com/tc39/ecma402/issues/128
var maxFraction = random(0, 20);
var minFraction = random(0, 20);
var rounded = BigDecimal.round(BigDecimal.BigDecimal(number.toString()), { maximumFractionDigits: maxFraction, roundingMode: 'half-up' });
function string(rounded, maxFraction) {
return rounded.toLocaleString('en-US', { maximumFractionDigits: maxFraction, minimumFractionDigits: Math.min(maxFraction, minFraction), useGrouping: false });
}
var a = Number(string(number, maxFraction)).toString();
var b = rounded.toString();
if (/^\-0\.?0*$/.test(a)) {
b = '-' + b;
}
if (a !== b) {
console.log(a);
console.log(b);
console.log(c);
throw new RangeError(number);
}
}
console.timeEnd('testing Number#toLocaleString');
console.timeEnd();
console.log('ok');
globalThis.BigDecimal = BigDecimal;
// benchmarks:
// 10 digits, 1000 digits
// atan, exp
const someBenchmarks = function (BigDecimal, BASE) {
const sd = function (decimalSignificantDigits) {
return Math.ceil(decimalSignificantDigits * (Math.log2(10) / Math.log2(BASE))) + (BASE !== 10 ? 2 : 0);
};
console.time('10 digits of π × 1000');
for (var i = 0; i < 1000; i += 1) {
var pi = BigDecimal.multiply(BigDecimal.BigDecimal(4), BigDecimal.atan(BigDecimal.BigDecimal(1), { maximumSignificantDigits: sd(10), roundingMode: 'half-even' }));
console.assert(pi.toFixed(10 - 1) === '3.141592654');
}
console.timeEnd('10 digits of π × 1000');
console.time('1000 digits of π');
var pi = BigDecimal.multiply(BigDecimal.BigDecimal(4), BigDecimal.atan(BigDecimal.BigDecimal(1), { maximumSignificantDigits: sd(1000), roundingMode: 'half-even' }));
console.timeEnd('1000 digits of π');
console.log(pi.toFixed(1000 - 1));
console.time('10 digits of ℯ × 1000');
for (var i = 0; i < 1000; i += 1) {
var e = BigDecimal.exp(BigDecimal.BigDecimal(1), { maximumSignificantDigits: sd(10), roundingMode: 'half-even' });
console.assert(e.toFixed(9) === '2.718281828');
}
console.timeEnd('10 digits of ℯ × 1000');
console.time('1000 digits of ℯ');
var e = BigDecimal.exp(BigDecimal.BigDecimal(1), { maximumSignificantDigits: sd(1000), roundingMode: 'half-even' });
console.timeEnd('1000 digits of ℯ');
console.log(e.toFixed(1000 - 1));
console.time('10 digits of ln(2) × 1000');
for (var i = 0; i < 1000; i += 1) {
var ln2 = BigDecimal.log(BigDecimal.BigDecimal(2), { maximumSignificantDigits: sd(10), roundingMode: 'half-even' });
console.assert(ln2.toFixed(10) === '0.6931471806');
}
console.timeEnd('10 digits of ln(2) × 1000');
console.time('1000 digits of ln(2)');
var ln2 = BigDecimal.log(BigDecimal.BigDecimal(2), { maximumSignificantDigits: sd(1000), roundingMode: 'half-even' });
console.timeEnd('1000 digits of ln(2)');
console.log(ln2.toFixed(1000));
};
console.log('%cUsing BigDecimal:', 'font-weight: bold');
someBenchmarks(BigDecimal, 10);
console.log('%cUsing BigFloat:', 'font-weight: bold');
someBenchmarks(BigFloat, 2);
globalThis.BigFloat = BigFloat;
console.assert(BigFloat.divide(BigFloat.BigFloat(49151), BigFloat.BigFloat(2**15)).toPrecision(1) === '1');
console.assert(BigFloat.divide(BigFloat.BigFloat(13835058055282163711n), BigFloat.BigFloat(2n**63n)).toPrecision(1) === '1');
console.assert(BigFloat.BigFloat(1).toPrecision(101) === '1.' + '0'.repeat(100));
console.assert(BigFloat.BigFloat(46892389.03583745).toPrecision(34) === '46892389.03583744913339614868164063');
console.assert(BigFloat.BigFloat(-9422.84286622639).toExponential(36) === '-9.422842866226390469819307327270507813e+3');
console.assert(BigFloat.exp(BigFloat.BigFloat(710), { maximumSignificantDigits: 1, roundingMode: 'half-even' }).toPrecision(1) === '2e+308');
console.assert(BigFloat.exp(BigFloat.BigFloat(-739), { maximumSignificantDigits: 9, roundingMode: 'half-even' }).toPrecision(4) === '1.139e-321');
console.assert(BigFloat.BigFloat(9.478349671985029e+100).toExponential(0) === '9e+100'); // bug
console.assert(BigFloat.BigFloat(9.5e+307).toExponential(0) === '9e+307');
console.assert(BigFloat.BigFloat(-9.460115477371994e+122).toExponential(0) === '-9e+122'); // bug
var x = BigFloat.log(BigFloat.BigFloat(8), {maximumSignificantDigits: 138, roundingMode: 'floor'});
x = BigFloat.divide(x, BigFloat.BigFloat(4));
console.assert(BigFloat.exp(BigFloat.BigFloat(x), { maximumSignificantDigits: 138, roundingMode: 'floor' }).toFixed(2) === '1.68'); // bug (infinite loop)
console.time('BigFloat#toExponential');
for (var c = 0; c < 10000; c += 1) {
var number = randomNumber();
var bigfloat = BigFloat.BigFloat(number);
var n = random(0, 100);
if (Math.abs(number) <= 999999999999999868928) {
console.assert(bigfloat.toFixed(n) === number.toFixed(n), bigfloat.toFixed(n), number.toFixed(n));
}
console.assert(bigfloat.toExponential(n) === number.toExponential(n), number, n, bigfloat.toExponential(n), number.toExponential(n));
console.assert(bigfloat.toPrecision(Math.min(n + 1, 100)) === number.toPrecision(Math.min(n + 1, 100)), number);
}
console.timeEnd('BigFloat#toExponential');
// default: 6836.679931640625 ms
var roundNumber = function (number, precision) {
if (Math.abs(number) * 2**53 === 1/0) {
return roundNumber(number / 2**53, precision) * 2**53;
}
var v = number * 2**(53-precision);
return v - (v - number);//?
};
console.time('Math for small values');
for (var c = 0; c < 10000; c += 1) {
var number = roundNumber(randomNumber(), 18);
//var number = 2;
//var number = -2.05986225550976e+168;
//var number = Number.MAX_VALUE;
//var number = 687.66796875;
//debugger;
if (number !== 0 && !Number.isNaN(number)) {
var bigfloat = BigFloat.BigFloat(number);
var f = 'sin cos atan exp log'.split(' ')[Math.floor(Math.random() * 5)];
//var f = 'exp';
//var f = 'cos';
var value = Math[f](number);
if (Math.abs(value) >= 2**-1022 && Math.abs(value) < 1/0) {
if (f !== 'log' || number > 0) {
var n = 20;
var a = BigFloat[f](bigfloat, {maximumSignificantDigits: 18, roundingMode: 'half-even'}).toPrecision(n);
var b = roundNumber(value, 18).toPrecision(n);
console.assert(a === b, number, f, a, b);
}
}
}
}
console.timeEnd('Math for small values');
console.time();
var s = 0;
for (var i = 0; i < 10000; i += 1) {
s += Math.cos(Number(BigInt(i)));
console.assert(s.toPrecision(20).length > 1);
}
console.timeEnd();
console.log(s);
globalThis.randomNumber = randomNumber;
globalThis.roundNumber = roundNumber;