计算pi的数字

时间:2013-01-04 17:57:39

标签: c++ floating-point gmp pi arbitrary-precision

我使用GMP库和C ++来编写Gauss-Legendre算法的实现来计算pi的数字。

它有正确的输出,但问题是我不知道输出“变坏”,因为我必须在代码中指定精度。

以下是使用64位精度的输出:3.141592653589793238 * 35 *,后两位数字不正确。

我的问题是,如果我想要pi的 n 位数,精确度 b 的位数,以及算法的迭代次数 i 将需要吗?

谢谢

1 个答案:

答案 0 :(得分:10)

高斯 - 勒让德算法(又名AGM算法)一直需要完全精确。

与Newton的Method迭代不同,AGM迭代不是自我纠正的。所以你从一开始就需要完全精确。此外,您需要额外的保护数字。

  

我的问题是,如果我想要pi的n位数,那么需要多少位精度b

首先,您需要将n(十进制)数字转换为b二进制位。那就是:

        log(10)
b = n ---------- + epsilon
        log(2)

其中epsilon是保护数字的数量。您需要多少取决于实现和舍入行为,但通常100位对于任何迭代次数都足够了。

至于您需要多少次迭代。这可以通过经验证据找到。

这是我编写的一个小应用程序的输出,使用Gauss-Legendre算法将Pi计算为1亿个数字:

================================================================
Computing pi to 100000000 digits:
Threads: 8

Starting AGM...         1.394965 seconds
Starting Iteration 0...    -3 (error in decimal digits)
Starting Iteration 1...    -9
Starting Iteration 2...    -20
Starting Iteration 3...    -42
Starting Iteration 4...    -85
Starting Iteration 5...    -173
Starting Iteration 6...    -347
Starting Iteration 7...    -696
Starting Iteration 8...    -1395
Starting Iteration 9...    -2792
Starting Iteration 10...    -5586
Starting Iteration 11...    -11175
Starting Iteration 12...    -22352
Starting Iteration 13...    -44706
Starting Iteration 14...    -89414
Starting Iteration 15...    -178829
Starting Iteration 16...    -357661
Starting Iteration 17...    -715324
Starting Iteration 18...    -1430650
Starting Iteration 19...    -2861302
Starting Iteration 20...    -5722607
Starting Iteration 21...    -11445216
Starting Iteration 22...    -22890435
Starting Iteration 23...    -45780871
Starting Iteration 24...    -91561745
Starting Iteration 25...    -183123492
AGM:                    118.796792 seconds
Finishing...            3.033239   seconds
Radix Conversion...     2.924844   seconds

Total Wall Time:        126.151086 seconds

CPU Utilization:        495.871%
CPU Efficiency:         61.984%

Writing to "pi.txt"...  Done

因此,对于1.83亿个数字,25次迭代就足够了。同样,它在每次迭代时都会加倍,因此您可以运行一些基本的对数数学来计算出所需的迭代次数。