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