@joshyzou/pisolver
Version:
calculates pi when you input the number of digits to calculate to.
59 lines (55 loc) • 2.16 kB
JavaScript
module.exports = async function calcPi(digits, numStr){
if (!digits) return "The number of digits must be a number!";
if (Number(digits).toString().toLowerCase() === "nan") return "The number of digits must be a number!"
let result = await pi_chudnovsky(Number(digits));
//console.log(result)
if (!numStr) return result.toString();
if (numStr.toString() === "true"){
return (result)
}else{
return (result.toString())
}
function pi_chudnovsky(digits){
//Calculate pi using Chudnovsky's series
//This calculates it in fixed point
one = 0n;
one = 10n**(BigInt(digits)+20n);
k = 1n;
a_k = one;
a_sum = one;
b_sum = 0n;
C = 640320n;
C3_OVER_24 = (C*C*C) / 24n;
while (1){
a_k *= -(6n*k-5n)*(2n*k-1n)*(6n*k-1n);
a_k /= k*k*k*C3_OVER_24;
a_sum += a_k;
b_sum += k * a_k;
k += 1n;
if (a_k == 0n)
break;
}
total = 13591409n*a_sum + 545140134n*b_sum;
[x,y] = pell_sqrt_10005( digits );
hexdigits = Math.floor(digits/1.20411998266)
hexchars = (426880n*x*one*(16n**(BigInt(hexdigits)+20n))) / (total*y);
pi = (426880n*x*one*one) / (total*y);
return pi;
}
function pell_sqrt_10005(digits){
// rational approximation to sqrt(10005) using pell equation
// use the previous 2 solutions to form the next solution in a Fibonacci style sequence
// so the values of x,y increase by a factor of approx. the golden ratio each iteration
D=10005n;
[x1,y1] = [1n,0n];
[x2,y2] = [4001n,40n];
y_target = 10n**(BigInt(digits/2 + 5));
while (1){
[x,y] = [x1*x2 + D*y1*y2, x1*y2 + y1*x2];
if ( y > y_target)
return [x,y];
[x1,y1] = [x2,y2];
[x2,y2] = [x,y];
}
}
}