• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * PI computation in Javascript using the QuickJS bignum extensions
3 */
4"use strict";
5"use bigint";
6
7/* compute PI with a precision of 'prec' bits */
8function calc_pi(prec) {
9    const CHUD_A = 13591409;
10    const CHUD_B = 545140134;
11    const CHUD_C = 640320;
12    const CHUD_C3 = 10939058860032000; /* C^3/24 */
13    const CHUD_BITS_PER_TERM = 47.11041313821584202247; /* log2(C/12)*3 */
14
15    /* return [P, Q, G] */
16    function chud_bs(a, b, need_G) {
17        var c, P, Q, G, P1, Q1, G1, P2, Q2, G2;
18        if (a == (b - 1)) {
19            G = (2 * b - 1) * (6 * b - 1) * (6 * b - 5);
20            P = BigFloat(G * (CHUD_B * b + CHUD_A));
21            if (b & 1)
22                P = -P;
23            G = BigFloat(G);
24            Q = BigFloat(b * b * b * CHUD_C3);
25        } else {
26            c = (a + b) >> 1;
27            [P1, Q1, G1] = chud_bs(a, c, true);
28            [P2, Q2, G2] = chud_bs(c, b, need_G);
29            P = P1 * Q2 + P2 * G1;
30            Q = Q1 * Q2;
31            if (need_G)
32                G = G1 * G2;
33            else
34                G = 0;
35        }
36        return [P, Q, G];
37    }
38
39    var n, P, Q, G;
40    /* number of serie terms */
41    n = Math.ceil(BigFloatEnv.prec / CHUD_BITS_PER_TERM) + 10;
42    [P, Q, G] = chud_bs(0, n, false);
43    Q = Q / (P + Q * CHUD_A);
44    G = (CHUD_C / 12) * BigFloat.sqrt(CHUD_C);
45    return Q * G;
46}
47
48(function() {
49    var r, n_digits, n_bits;
50    if (typeof scriptArgs != "undefined") {
51        if (scriptArgs.length < 2) {
52            print("usage: pi n_digits");
53            return;
54        }
55        n_digits = scriptArgs[1];
56    } else {
57        n_digits = 1000;
58    }
59    n_bits = Math.ceil(n_digits * Math.log2(10));
60    /* we add more bits to reduce the probability of bad rounding for
61       the last digits */
62    BigFloatEnv.setPrec( () => {
63        r = calc_pi();
64        print(r.toFixed(n_digits, BigFloatEnv.RNDZ));
65    }, n_bits + 32);
66})();
67