原文:A Million Digits of Pi in 9 Lines of Javascript

作者:Andrew Jennings

BigInt 已经可以在 JavaScript 中使用了,至少在 Firefox 和 Chrome 中如此。对于高精度计算,我最喜欢做的就是计算圆周率,使用最简单的方法,也就是说只使用加减乘除。

你可以找到很多计算圆周率的公式,但我最喜欢的是这个:

出于某些原因,它没有被大多数圆周率公式列表记载,但是我喜欢它,因为它很简单。我不用查任何东西就能很容易地回想起来,只需要记住前两项和三个被乘数简单的变化规则。在我上小学的时候,一个叔叔告诉了我,几十年来我一直没有忘记它。我一直不知道它为什么有效,直到这个月我开始研究它。(提示:泰勒级数

它只用了加法、乘法和除法、没有开方运算、直接计算圆周率(很多方法只能计算出它的倒数)。虽然有些复杂的公式收敛得更快,但这个简单的公式也能达到大约每项收敛 0.6 个小数位的速度。

要在 JavaScript 中使用 BigInt,只需要在整数字面量后面加上“n”后缀。下面是我们如何利用这个公式来使用 JavaScript 计算圆周率的前一千位:

1
2
3
4
5
6
7
8
9
let i = 1n;
let x = 3n * (10n ** 1020n);
let pi = x;
while (x > 0) {
x = x * i / ((i + 1n) * 4n);
pi += x / (i + 2n);
i += 2n;
}
console.log(pi / (10n ** 20n));

我们只需要依次计算小数点向右移动 1020 位的每项——后面的太小所以无关紧要——然后把它们加起来,去掉最后 20 位,最后打印出结果。

这段代码可以在 Chrome、Firefox 和最新版 Nodejs 中运行。下面是它在 Macbook Pro 2014(4核 i7 2.5GHz,只使用了一个核心):

要增加计算的位数,只需要简单地增加第二行的指数就行了,下面是计算一百万位圆周率的 JavaScript 代码:

1
2
3
4
5
6
7
8
9
let i = 1n;
let x = 3n * (10n ** 1000020n);
let pi = x;
while (x > 0) {
x = x * i / ((i + 1n) * 4n);
pi += x / (i + 2n);
i += 2n;
}
console.log(pi / (10n ** 20n));

这在 Chrome 控制台就可以做到。在我的机子上大约需要一个小时。然而 Firefox 好像无法处理过大的数字。

这是一个浏览器中的圆周率计算器,它使用了上面的代码,并做了一些修改以展示计算进展。