JavaScript Pi Spigot Algorithm not working

433 views Asked by At

I have translated the following C++ code:

#include <iostream>
using namespace std;
#define NDIGITS 100
#define LEN (NDIGITS/4+1)*14

long a[LEN];
long b;
long c = LEN;
long d;
long e = 0;
long f = 10000;
long g;
long h = 0;
int main(void) {
    cout<<b<<endl;
    for(; (b=c-=14) > 0 ;){
        for(; --b > 0 ;){
            d *= b;
            if( h == 0 )
                d += 2000*f;
            else
                d += a[b]*f;
            g=b+b-1;
            a[b] = d % g;
            d /= g;
        }
        h = printf("%ld",e+d/f);
        d = e = d % f;
    }
    getchar();
    return 0;
}

Into JavaScript:

function mod(n, m) {
    return ((m % n) + n) % n;
} // mod function to fix javascript modulo bug
function calculate(NDIGITS){
    var LEN = (NDIGITS / 4 + 1) * 14,
        out = "",
        a = [],
        b = 0,
        c = LEN,
        d = 0,
        e = 0,
        f = 10000,
        g = 0,
        h = 0;
    for( ; a.length != LEN; a.push(0));
    for( ; (b=c-=14) > 0 ; ){
        for(; --b > 0 ;){
            d *= b;
            if(h == 0)
                d += 2000*f;
            else
                d += a[b]*f;
            g=b+b-1;
            a[b] = mod(d, g);
            d /= g;
        };
        h = 4;
        out += e + d / f;
        d = e = mod(d, f);
    };
    return out;
};
calculate(100);

The problem is, the C++ (which is correct) output looks like this:

314159265358979323846264338327952884197169399375105820974944592307816406286208998628034825342117067

But the JavaScript (which is wrong) output looks like this:

3141.59265358979345928.3358757688158002.0385670499462603.1996016540431161.44919092773639662.2465149363658988.6127837844255865.38922090756173.61883094848226189.6324225085448150.3443440509899223.2179589088062808.1943642437717982.8973948575671840.86646781354151140.38694447211833938.5632867441137341.458720505086448.7384444661472807.14448220310268936.5521832735086764.9290682040381301.76585926509928223.4135991546457438.115065010927

Where did I mess up in my coding? Thanks for the help.

1

There are 1 answers

2
Rainer Rillke On BEST ANSWER
  1. JavaScript does floating point division.
  2. Arguments exchanged in modulo calculation function.

Here is code that produces the same result as the C++ code provided for the given sample (100) digits:

function mod(m, n) {
        return ((m % n) + n) % n;
} // mod function to fix javascript modulo bug

function calculate(NDIGITS) {
    var LEN = (NDIGITS / 4 + 1) * 14,
        out = "",
        a = [],
        b = 0,
        c = LEN,
        d = 0,
        e = 0,
        f = 10000,
        g = 0,
        h = 0;

    for (; a.length !== LEN; a.push(0));
    for (; (b = c -= 14) > 0;) {
        for (; --b > 0;) {
            d *= b;
            if (h === 0) {
                d += 2000 * f;
            } else {
                d += a[b] * f;
            }
            g = b + b - 1;
            a[b] = mod(d, g);
            d = Math.floor(d / g);
        }
        h = Math.floor(e + d / f);
        out += h;
        h = h.length;
        d = e = mod(d, f);
    }
    return out;
}
console.log(calculate(100));