quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

pi_bigfloat.js (1973B)


      1 /*
      2  * PI computation in Javascript using the QuickJS bigfloat type
      3  * (binary floating point)
      4  */
      5 "use strict";
      6 
      7 /* compute PI with a precision of 'prec' bits */
      8 function calc_pi() {
      9     const CHUD_A = 13591409n;
     10     const CHUD_B = 545140134n;
     11     const CHUD_C = 640320n;
     12     const CHUD_C3 = 10939058860032000n; /* 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 - 1n)) {
     19             G = (2n * b - 1n) * (6n * b - 1n) * (6n * b - 5n);
     20             P = BigFloat(G * (CHUD_B * b + CHUD_A));
     21             if (b & 1n)
     22                 P = -P;
     23             G = BigFloat(G);
     24             Q = BigFloat(b * b * b * CHUD_C3);
     25         } else {
     26             c = (a + b) >> 1n;
     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 = 0l;
     35         }
     36         return [P, Q, G];
     37     }
     38 
     39     var n, P, Q, G;
     40     /* number of serie terms */
     41     n = BigInt(Math.ceil(BigFloatEnv.prec / CHUD_BITS_PER_TERM)) + 10n;
     42     [P, Q, G] = chud_bs(0n, n, false);
     43     Q = Q / (P + Q * BigFloat(CHUD_A));
     44     G = BigFloat((CHUD_C / 12n)) * BigFloat.sqrt(BigFloat(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 })();