我正在尝试使用此公式将Pi解析为JavaScript中的n个数字:
#!/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在具有任意长度整数支持的语言中的工作方式。
但是在JavaScript中,代码会生成正确的值,直到小数点后18位,然后数字会变得很大。更糟糕的是,如果给该函数一个大的数字(如10000),它将在无限循环中运行。
[当我尝试写一个大数字并附加n
时(如建议的here):
var a = 1000000000000000000000000000n
我得到:
typein:1:8 SyntaxError: identifier starts immediately after numeric literal:
typein:1:8 var a = 1000000000000000000000000000n
typein:1:8 ........^
如何在JavaScript中表示任意长度的整数?
感谢评论,将JS引擎从SpiderMonkey更改为Node可以解决此问题。最终代码如下:
#!/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))
现在,它可以使用某些系统的内存来解决任何数字(5,000位数字约为40 MiB)。
该代码删除了Math.floor()函数,因为BigInt计算为整数。这里将不计算任意精度的浮点数。