1"use strict";
2
3function assert(actual, expected, message) {
4    if (arguments.length == 1)
5        expected = true;
6
7    if (actual === expected)
8        return;
9
10    if (actual !== null && expected !== null
11    &&  typeof actual == 'object' && typeof expected == 'object'
12    &&  actual.toString() === expected.toString())
13        return;
14
15    throw Error("assertion failed: got |" + actual + "|" +
16                ", expected |" + expected + "|" +
17                (message ? " (" + message + ")" : ""));
18}
19
20function assertThrows(err, func)
21{
22    var ex;
23    ex = false;
24    try {
25        func();
26    } catch(e) {
27        ex = true;
28        assert(e instanceof err);
29    }
30    assert(ex, true, "exception expected");
31}
32
33// load more elaborate version of assert if available
34try { __loadScript("test_assert.js"); } catch(e) {}
35
36/*----------------*/
37
38function bigint_pow(a, n)
39{
40    var r, i;
41    r = 1n;
42    for(i = 0n; i < n; i++)
43        r *= a;
44    return r;
45}
46
47/* a must be < b */
48function test_less(a, b)
49{
50    assert(a < b);
51    assert(!(b < a));
52    assert(a <= b);
53    assert(!(b <= a));
54    assert(b > a);
55    assert(!(a > b));
56    assert(b >= a);
57    assert(!(a >= b));
58    assert(a != b);
59    assert(!(a == b));
60}
61
62/* a must be numerically equal to b */
63function test_eq(a, b)
64{
65    assert(a == b);
66    assert(b == a);
67    assert(!(a != b));
68    assert(!(b != a));
69    assert(a <= b);
70    assert(b <= a);
71    assert(!(a < b));
72    assert(a >= b);
73    assert(b >= a);
74    assert(!(a > b));
75}
76
77function test_bigint1()
78{
79    var a, r;
80
81    test_less(2n, 3n);
82    test_eq(3n, 3n);
83
84    test_less(2, 3n);
85    test_eq(3, 3n);
86
87    test_less(2.1, 3n);
88    test_eq(Math.sqrt(4), 2n);
89
90    a = bigint_pow(3n, 100n);
91    assert((a - 1n) != a);
92    assert(a == 515377520732011331036461129765621272702107522001n);
93    assert(a == 0x5a4653ca673768565b41f775d6947d55cf3813d1n);
94
95    r = 1n << 31n;
96    assert(r, 2147483648n, "1 << 31n === 2147483648n");
97
98    r = 1n << 32n;
99    assert(r, 4294967296n, "1 << 32n === 4294967296n");
100}
101
102function test_bigint2()
103{
104    assert(BigInt(""), 0n);
105    assert(BigInt("  123"), 123n);
106    assert(BigInt("  123   "), 123n);
107    assertThrows(SyntaxError, () => { BigInt("+") } );
108    assertThrows(SyntaxError, () => { BigInt("-") } );
109    assertThrows(SyntaxError, () => { BigInt("\x00a") } );
110    assertThrows(SyntaxError, () => { BigInt("  123  r") } );
111}
112
113function test_divrem(div1, a, b, q)
114{
115    var div, divrem, t;
116    div = BigInt[div1];
117    divrem = BigInt[div1 + "rem"];
118    assert(div(a, b) == q);
119    t = divrem(a, b);
120    assert(t[0] == q);
121    assert(a == b * q + t[1]);
122}
123
124function test_idiv1(div, a, b, r)
125{
126    test_divrem(div, a, b, r[0]);
127    test_divrem(div, -a, b, r[1]);
128    test_divrem(div, a, -b, r[2]);
129    test_divrem(div, -a, -b, r[3]);
130}
131
132/* QuickJS BigInt extensions */
133function test_bigint_ext()
134{
135    var r;
136    assert(BigInt.floorLog2(0n) === -1n);
137    assert(BigInt.floorLog2(7n) === 2n);
138
139    assert(BigInt.sqrt(0xffffffc000000000000000n) === 17592185913343n);
140    r = BigInt.sqrtrem(0xffffffc000000000000000n);
141    assert(r[0] === 17592185913343n);
142    assert(r[1] === 35167191957503n);
143
144    test_idiv1("tdiv", 3n, 2n, [1n, -1n, -1n, 1n]);
145    test_idiv1("fdiv", 3n, 2n, [1n, -2n, -2n, 1n]);
146    test_idiv1("cdiv", 3n, 2n, [2n, -1n, -1n, 2n]);
147    test_idiv1("ediv", 3n, 2n, [1n, -2n, -1n, 2n]);
148}
149
150function test_bigfloat()
151{
152    var e, a, b, sqrt2;
153
154    assert(typeof 1n === "bigint");
155    assert(typeof 1l === "bigfloat");
156    assert(1 == 1.0l);
157    assert(1 !== 1.0l);
158
159    test_less(2l, 3l);
160    test_eq(3l, 3l);
161
162    test_less(2, 3l);
163    test_eq(3, 3l);
164
165    test_less(2.1, 3l);
166    test_eq(Math.sqrt(9), 3l);
167
168    test_less(2n, 3l);
169    test_eq(3n, 3l);
170
171    e = new BigFloatEnv(128);
172    assert(e.prec == 128);
173    a = BigFloat.sqrt(2l, e);
174    assert(a === BigFloat.parseFloat("0x1.6a09e667f3bcc908b2fb1366ea957d3e", 0, e));
175    assert(e.inexact === true);
176    assert(BigFloat.fpRound(a) == 0x1.6a09e667f3bcc908b2fb1366ea95l);
177
178    b = BigFloatEnv.setPrec(BigFloat.sqrt.bind(null, 2), 128);
179    assert(a === b);
180
181    assert(BigFloat.isNaN(BigFloat(NaN)));
182    assert(BigFloat.isFinite(1l));
183    assert(!BigFloat.isFinite(1l/0l));
184
185    assert(BigFloat.abs(-3l) === 3l);
186    assert(BigFloat.sign(-3l) === -1l);
187
188    assert(BigFloat.exp(0.2l) === 1.2214027581601698339210719946396742l);
189    assert(BigFloat.log(3l) === 1.0986122886681096913952452369225256l);
190    assert(BigFloat.pow(2.1l, 1.6l) === 3.277561666451861947162828744873745l);
191
192    assert(BigFloat.sin(-1l) === -0.841470984807896506652502321630299l);
193    assert(BigFloat.cos(1l) === 0.5403023058681397174009366074429766l);
194    assert(BigFloat.tan(0.1l) === 0.10033467208545054505808004578111154l);
195
196    assert(BigFloat.asin(0.3l) === 0.30469265401539750797200296122752915l);
197    assert(BigFloat.acos(0.4l) === 1.1592794807274085998465837940224159l);
198    assert(BigFloat.atan(0.7l) === 0.610725964389208616543758876490236l);
199    assert(BigFloat.atan2(7.1l, -5.1l) === 2.1937053809751415549388104628759813l);
200
201    assert(BigFloat.floor(2.5l) === 2l);
202    assert(BigFloat.ceil(2.5l) === 3l);
203    assert(BigFloat.trunc(-2.5l) === -2l);
204    assert(BigFloat.round(2.5l) === 3l);
205
206    assert(BigFloat.fmod(3l,2l) === 1l);
207    assert(BigFloat.remainder(3l,2l) === -1l);
208
209    /* string conversion */
210    assert((1234.125l).toString(), "1234.125");
211    assert((1234.125l).toFixed(2), "1234.13");
212    assert((1234.125l).toFixed(2, "down"), "1234.12");
213    assert((1234.125l).toExponential(), "1.234125e+3");
214    assert((1234.125l).toExponential(5), "1.23413e+3");
215    assert((1234.125l).toExponential(5, BigFloatEnv.RNDZ), "1.23412e+3");
216    assert((1234.125l).toPrecision(6), "1234.13");
217    assert((1234.125l).toPrecision(6, BigFloatEnv.RNDZ), "1234.12");
218
219    /* string conversion with binary base */
220    assert((0x123.438l).toString(16), "123.438");
221    assert((0x323.438l).toString(16), "323.438");
222    assert((0x723.438l).toString(16), "723.438");
223    assert((0xf23.438l).toString(16), "f23.438");
224    assert((0x123.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "123.44");
225    assert((0x323.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "323.44");
226    assert((0x723.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "723.44");
227    assert((0xf23.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "f23.44");
228    assert((0x0.0000438l).toFixed(6, BigFloatEnv.RNDNA, 16), "0.000044");
229    assert((0x1230000000l).toFixed(1, BigFloatEnv.RNDNA, 16), "1230000000.0");
230    assert((0x123.438l).toPrecision(5, BigFloatEnv.RNDNA, 16), "123.44");
231    assert((0x123.438l).toPrecision(5, BigFloatEnv.RNDZ, 16), "123.43");
232    assert((0x323.438l).toPrecision(5, BigFloatEnv.RNDNA, 16), "323.44");
233    assert((0x723.438l).toPrecision(5, BigFloatEnv.RNDNA, 16), "723.44");
234    assert((-0xf23.438l).toPrecision(5, BigFloatEnv.RNDD, 16), "-f23.44");
235    assert((0x123.438l).toExponential(4, BigFloatEnv.RNDNA, 16), "1.2344p+8");
236}
237
238function test_bigdecimal()
239{
240    assert(1m === 1m);
241    assert(1m !== 2m);
242    test_less(1m, 2m);
243    test_eq(2m, 2m);
244
245    test_less(1, 2m);
246    test_eq(2, 2m);
247
248    test_less(1.1, 2m);
249    test_eq(Math.sqrt(4), 2m);
250
251    test_less(2n, 3m);
252    test_eq(3n, 3m);
253
254    assert(BigDecimal("1234.1") === 1234.1m);
255    assert(BigDecimal("    1234.1") === 1234.1m);
256    assert(BigDecimal("    1234.1  ") === 1234.1m);
257
258    assert(BigDecimal(0.1) === 0.1m);
259    assert(BigDecimal(123) === 123m);
260    assert(BigDecimal(true) === 1m);
261
262    assert(123m + 1m === 124m);
263    assert(123m - 1m === 122m);
264
265    assert(3.2m * 3m === 9.6m);
266    assert(10m / 2m === 5m);
267    assertThrows(RangeError, () => { 10m / 3m } );
268
269    assert(10m % 3m === 1m);
270    assert(-10m % 3m === -1m);
271
272    assert(1234.5m ** 3m === 1881365963.625m);
273    assertThrows(RangeError, () => { 2m ** 3.1m } );
274    assertThrows(RangeError, () => { 2m ** -3m } );
275
276    assert(BigDecimal.sqrt(2m,
277                       { roundingMode: "half-even",
278                         maximumSignificantDigits: 4 }) === 1.414m);
279    assert(BigDecimal.sqrt(101m,
280                       { roundingMode: "half-even",
281                         maximumFractionDigits: 3 }) === 10.050m);
282    assert(BigDecimal.sqrt(0.002m,
283                       { roundingMode: "half-even",
284                         maximumFractionDigits: 3 }) === 0.045m);
285
286    assert(BigDecimal.round(3.14159m,
287                       { roundingMode: "half-even",
288                         maximumFractionDigits: 3 }) === 3.142m);
289
290    assert(BigDecimal.add(3.14159m, 0.31212m,
291                          { roundingMode: "half-even",
292                            maximumFractionDigits: 2 }) === 3.45m);
293    assert(BigDecimal.sub(3.14159m, 0.31212m,
294                          { roundingMode: "down",
295                            maximumFractionDigits: 2 }) === 2.82m);
296    assert(BigDecimal.mul(3.14159m, 0.31212m,
297                          { roundingMode: "half-even",
298                            maximumFractionDigits: 3 }) === 0.981m);
299    assert(BigDecimal.mod(3.14159m, 0.31211m,
300                          { roundingMode: "half-even",
301                            maximumFractionDigits: 4 }) === 0.0205m);
302    assert(BigDecimal.div(20m, 3m,
303                       { roundingMode: "half-even",
304                         maximumSignificantDigits: 3 }) === 6.67m);
305    assert(BigDecimal.div(20m, 3m,
306                       { roundingMode: "half-even",
307                         maximumFractionDigits: 50 }) ===
308           6.66666666666666666666666666666666666666666666666667m);
309
310    /* string conversion */
311    assert((1234.125m).toString(), "1234.125");
312    assert((1234.125m).toFixed(2), "1234.13");
313    assert((1234.125m).toFixed(2, "down"), "1234.12");
314    assert((1234.125m).toExponential(), "1.234125e+3");
315    assert((1234.125m).toExponential(5), "1.23413e+3");
316    assert((1234.125m).toExponential(5, "down"), "1.23412e+3");
317    assert((1234.125m).toPrecision(6), "1234.13");
318    assert((1234.125m).toPrecision(6, "down"), "1234.12");
319    assert((-1234.125m).toPrecision(6, "floor"), "-1234.13");
320}
321
322test_bigint1();
323test_bigint2();
324test_bigint_ext();
325test_bigfloat();
326test_bigdecimal();
327