我在尝试各种方法来实现一个程序,它可以按顺序给出圆周率的数字。我尝试了泰勒级数方法,但事实证明它收敛得非常慢(当我在一段时间后将我的结果与在线值进行比较时)。总之,我在尝试更好的算法。
因此,在编写程序时,我遇到了一个问题,就像所有算法一样:我如何知道我计算的n位数字是准确的?
我在尝试各种方法来实现一个程序,它可以按顺序给出圆周率的数字。我尝试了泰勒级数方法,但事实证明它收敛得非常慢(当我在一段时间后将我的结果与在线值进行比较时)。总之,我在尝试更好的算法。
因此,在编写程序时,我遇到了一个问题,就像所有算法一样:我如何知道我计算的n位数字是准确的?
您可以使用多种方法,看看它们是否收敛到相同的答案。或者从网上抓一些。Chudnovsky算法通常被用作计算圆周率的一种非常快速的方法。http://www.craig-wood.com/nick/articles/pi-chudnovsky/
泰勒级数是一种近似的方法。如前所述,它收敛得很慢。
泰勒级数的部分和可以被证明在离圆周率真值的下一项的乘数之内。
其他近似圆周率的方法也有类似的方法来计算最大误差。
我们知道这一点,因为我们可以用数学证明它。
因为我是目前圆周率数字最多的世界纪录保持者,我想补充一下我的观点:
除非你真的要创造一项新的世界纪录,否则通常的做法是将计算出的数字与已知值进行验证。这很简单。
事实上,我有一个网页,列出了数字片段,用于验证它们的计算:http://www.numberworld.org/digits/Pi/
但当你进入世界纪录领域时,就没有什么可以与之相比了。
从历史上看,验证计算数字是否正确的标准方法是使用第二种算法重新计算数字。因此,如果任何一个计算出错,末尾的数字就不匹配。
这通常是所需时间的两倍多(因为第二个算法通常更慢)。但一旦你进入了从未计算过的数字和新的世界纪录的未知领域,这是验证计算数字的唯一方法。
在超级计算机创造记录的年代,通常使用两种不同的AGM算法:
Gauss-Legendre算法 Borwein的算法
这两个算法都是O(nlog (N)²)算法很容易实现。
然而,现在的情况有点不同。在最近的三项世界纪录中,我们没有执行两次计算,而是使用已知最快的公式(Chudnovsky公式)只执行了一次计算:
这种算法很难实现,但比AGM算法快得多。
然后我们用BBP公式来验证二进制数字的提取。
这个公式允许您计算任意二进制数字,而无需计算之前的所有数字。因此,它用于验证最后几个计算的二进制数字。因此,它比完整的计算要快得多。
这样做的好处是:
只需要一个昂贵的计算。
缺点是:
需要实现Bailey-Borwein-Plouffe (BBP)公式。 需要另一个步骤来验证从二进制到十进制的基数转换。
我已经掩盖了一些细节,为什么验证最后几个数字意味着所有数字都是正确的。但是很容易看出这一点,因为任何计算错误都会传播到最后一位。
最后一步(验证转换)实际上相当重要。之前的一个世界纪录保持者实际上把我们叫出来了,因为一开始,我没有充分描述它是如何工作的。
所以我从我的博客中截取了这个片段:
N = # of decimal digits desired
p = 64-bit prime number
使用10进制算法计算A,使用二进制算法计算B。
如果A = B,那么“极有可能”,转换是正确的。
欲进一步阅读,请参阅我的博客文章《圆周率- 5万亿位数字》。
毫无疑问,为了你的目的(我认为这只是一个编程练习),最好的方法是将你的结果与网络上的圆周率数字列表进行核对。
我们怎么知道这些值是正确的呢?我可以说有计算机科学的方法来证明一个算法的实现是正确的。
从更实际的角度来说,如果不同的人使用不同的算法,并且他们都同意(选一个数字)小数点后十位(百万个,随便什么),那应该会给你一种温暖而模糊的感觉,他们是对的。
历史上,威廉·尚克斯在1873年将圆周率精确到小数点后707位。可怜的家伙,他从小数点后528位开始算错了。
非常有趣的是,1995年发布了一种算法,它可以直接计算圆周率的第n位(以16为底),而不需要计算之前的所有数字!
最后,我希望你最初的算法不是/4 = 1 - 1/3 + 1/5 - 1/7 +…这可能是最简单的编程方式,但也是最慢的编程方式之一。请查看维基百科上关于圆周率的文章,以获得更快的方法。
你可以试着计算sin(/2)(或者cos(/2))使用sin和cos的(相当)快速收敛幂级数。(更好的方法是:使用各种加倍公式计算更接近x=0的值,从而加快收敛速度。)
顺便说一句,对于tan(x)来说,比使用级数更好的是,计算cos(x)作为一个黑盒(例如,你可以使用上面的泰勒级数)是通过牛顿做根查找。当然还有更好的算法,但如果你不想验证大量的数字,这就足够了(而且实现起来并不复杂,你只需要一点微积分就能理解它为什么有效)。