0

I am trying to solve Pi till n number of digits in JavaScript with this formula:

#!/usr/bin/env js60

function calculatePi(n) {
    var q = t = k = 1
    var m = x = 3
    var n = n + 1
    var r = 0
    str = ''

    while (str.length < n) {
        if (4 * q + r - t < m * t) {
            str += m

            var rr = r
            r = 10 * (r - m * t)
            m = Math.floor((10 * (3 * q + rr)) / t - 10 * m)
            q = 10 * q
        }

        else {
            m = Math.floor(((q * (7 * k + 2)) + (r * x)) / (t * x))
            r = ((2 * q) + r) * x
            t = t * x
            q = q * k
            k = k + 1
            x = x + 2
        }
    }

    return str.slice(0, 1) + '.' + str.slice(1)
}

print(calculatePi(19))

Here's how it works in a language with arbitrary length integer support.

But in JavaScript the code generate correct values till the 18 decimal places, and after that the number gets really big to work with. Worse, if the function is given a large number like 10000, it will run in a infinite loop.

When I am trying to write a big number with an n appended to it (as suggested here):

var a = 1000000000000000000000000000n

I get:

typein:1:8 SyntaxError: identifier starts immediately after numeric literal:
typein:1:8 var a = 1000000000000000000000000000n
typein:1:8 ........^

How can I represent an arbitrary length integer in JavaScript?

15 Volts
  • 1,946
  • 15
  • 37

1 Answers1

-1

Thanks to the comments, changing the JS engine from SpiderMonkey to Node solved the issue. The final code looked like:

#!/usr/bin/env node

function calculatePi(n) {
    var one = 1n, two = 2n, three = 3n, seven = 7n, ten = 10n
    var q = t = k = one
    var m = x = three
    var n = BigInt(n) + one
    var r = 0n
    str = ''

    while (str.length < n) {
        if (4n * q + r - t < m * t) {
            str += m

            var rr = r
            r = ten * (r - m * t)
            m = (ten * (three * q + rr)) / t - ten * m
            q *= ten
        }

        else {
            t *= x
            m = (q * (seven * k + two) + (r * x)) / t
            r = ((two * q) + r) * x
            q *= k
            k += one
            x += two
        }
    }
    return str.slice(0, 1) + '.' + str.slice(1)
}

console.log(calculatePi(5000))

Now it can solve any digits using some system's memory (around 40 MiB for 5,000 digits).

The code removed Math.floor() function because BigInt calculation are Integers. A floating point number with arbitrary precision is not going to be calculated here.

15 Volts
  • 1,946
  • 15
  • 37