javascriptalgorithmpi

How to get larger doubles in Javascript


I am trying to caculate pi to a large amount of decimal places using the Gauss–Legendre algorithm as seen below

enter image description here

However, it only gives back around 15 digits of pi. Apparently this is because Mathematical operations in Javascript are performed using 64-bit floating point values and 16 digits of precision is right around the limit of what they can represent accurately.

This is my code

let a = 1,
    b = 1 / Math.sqrt(2),
    t = 1 / 4,
    p = 1;

let i = 0;
while (a - b < 3) {
    i++;

    let an = (a + b) / 2;
    b = Math.sqrt(a * b);
    t = t - p * (a - an) ** 2;
    p = 2 * p;

    a = an;

    if (i == 100) break;
    let pi = (a + b) ** 2 / (4 * t);
    console.log(pi);
}

I was wondering if there was any work around to get javascript to return more digits of pi. Thanks in Advance


Solution

  • Here's an interpretation using Decimal.js, with a desired precision of 150 digits of PI... (Note that "Full page" mode of "Run code snippet" provides a better review of the results.)

    <script src="https://cdnjs.cloudflare.com/ajax/libs/decimal.js/10.4.2/decimal.min.js"></script>
    
    <script>
    
    desiredPiDigits = 150;
    Decimal.precision = desiredPiDigits + 5;
    
    let desiredPiPrecision = new Decimal( 1 ).div( 10 ** desiredPiDigits );
    let maxIterations = 50;
    
    let a = new Decimal( 1 ),
        b = new Decimal( 1 ).div( Decimal.sqrt( 2 ) ),
        t = new Decimal( 0.25 ),
        p = new Decimal( 1 );
    
    let i = maxIterations;
    while ( desiredPiPrecision.lt( a.sub( b ).abs() ) ) {
    
        let an = a.add( b ).div( 2 );
        b = a.mul( b ).sqrt();
        t = t.sub( p.mul( a.sub( an ).pow( 2 ) ) );
        p = p.mul( 2 );
    
        a = an;
    
        let pi = a.add( b ).pow( 2 ).div( t.mul( 4 ) );
        console.log( pi.toString().slice( 0, desiredPiDigits + 1 ) );
        
        if (--i === 0) break;
    }
    
    </script>