获得π值的最快方法是什么?

What is the fastest way to get the value of π?

提问人:C. K. Young 提问时间:8/1/2008 最后编辑:OmGC. K. Young 更新时间:3/27/2023 访问量:69308

问:

我正在寻找获得π价值的最快方法,作为个人挑战。更具体地说,我使用的方法不涉及使用常量,例如 ,或对数字进行硬编码。#defineM_PI

下面的程序测试了我所知道的各种方式。从理论上讲,内联组装版本是最快的选择,尽管显然不是便携式的。我已将其作为基线,以便与其他版本进行比较。在我的测试中,使用内置功能,该版本在 GCC 4.2 上是最快的,因为它会自动折叠成一个常量。指定后,版本最快。4 * atan(1)atan(1)-fno-builtinatan2(0, -1)

以下是主要的测试程序():pitimes.c

#include <math.h>
#include <stdio.h>
#include <time.h>

#define ITERS 10000000
#define TESTWITH(x) {                                                       \
    diff = 0.0;                                                             \
    time1 = clock();                                                        \
    for (i = 0; i < ITERS; ++i)                                             \
        diff += (x) - M_PI;                                                 \
    time2 = clock();                                                        \
    printf("%s\t=> %e, time => %f\n", #x, diff, diffclock(time2, time1));   \
}

static inline double
diffclock(clock_t time1, clock_t time0)
{
    return (double) (time1 - time0) / CLOCKS_PER_SEC;
}

int
main()
{
    int i;
    clock_t time1, time2;
    double diff;

    /* Warmup. The atan2 case catches GCC's atan folding (which would
     * optimise the ``4 * atan(1) - M_PI'' to a no-op), if -fno-builtin
     * is not used. */
    TESTWITH(4 * atan(1))
    TESTWITH(4 * atan2(1, 1))

#if defined(__GNUC__) && (defined(__i386__) || defined(__amd64__))
    extern double fldpi();
    TESTWITH(fldpi())
#endif

    /* Actual tests start here. */
    TESTWITH(atan2(0, -1))
    TESTWITH(acos(-1))
    TESTWITH(2 * asin(1))
    TESTWITH(4 * atan2(1, 1))
    TESTWITH(4 * atan(1))

    return 0;
}

以及仅适用于 x86 和 x64 系统的内联汇编内容 ():fldpi.c

double
fldpi()
{
    double pi;
    asm("fldpi" : "=t" (pi));
    return pi;
}

以及构建我正在测试的所有配置的构建脚本():build.sh

#!/bin/sh
gcc -O3 -Wall -c           -m32 -o fldpi-32.o fldpi.c
gcc -O3 -Wall -c           -m64 -o fldpi-64.o fldpi.c

gcc -O3 -Wall -ffast-math  -m32 -o pitimes1-32 pitimes.c fldpi-32.o
gcc -O3 -Wall              -m32 -o pitimes2-32 pitimes.c fldpi-32.o -lm
gcc -O3 -Wall -fno-builtin -m32 -o pitimes3-32 pitimes.c fldpi-32.o -lm
gcc -O3 -Wall -ffast-math  -m64 -o pitimes1-64 pitimes.c fldpi-64.o -lm
gcc -O3 -Wall              -m64 -o pitimes2-64 pitimes.c fldpi-64.o -lm
gcc -O3 -Wall -fno-builtin -m64 -o pitimes3-64 pitimes.c fldpi-64.o -lm

除了在各种编译器标志之间进行测试(我也比较了 32 位和 64 位,因为优化不同),我还尝试切换测试顺序。但是,该版本仍然每次都名列前茅。atan2(0, -1)

性能 算法 语言无关的 Unix Pi

评论

2赞 erikkallen 12/23/2009
为什么你认为使用 atan(1) 与使用 M_PI 不同?如果你只使用算术运算,我会理解你为什么要这样做,但对于 atan,我不明白这一点。
1赞 C. K. Young 12/24/2009
@erik:并非所有语言都有内置常量,例如 .我试图找到一种“权威”方法来获取 pi 的(浮点)值,该值(理论上)适用于各种语言(和/或其内置库)。我目前首选的方法是使用 ,但也许有更好的方法。M_PIatan2(0, -1)
11赞 Tilo 10/28/2011
问题是:为什么不想使用常量?例如,由库定义还是由您自己定义?计算 Pi 是浪费 CPU 周期,因为这个问题已经一遍又一遍地被解决到许多有效数字,远远大于日常计算所需的数字
5赞 C. K. Young 7/11/2014
@HopelessN00b 在我说的英语方言中,“优化”是用“s”拼写的,而不是“z”(顺便说一句,发音为“zed”,而不是“zee”;-))。(如果您查看评论历史记录,这也不是我第一次不得不恢复这种编辑。
3赞 C. K. Young 5/2/2015
@Pacerier 参见 en.wiktionary.org/wiki/boggleen.wiktionary.org/wiki/mindboggling

答:

81赞 Leon Bambrick 8/1/2008 #1

这是我在高中学到的计算圆周率技术的一般描述。

我之所以分享这个,是因为我认为它足够简单,任何人都可以无限期地记住它,而且它教会了你“蒙特卡洛”方法的概念——这是得出答案的统计方法,这些答案似乎不能立即通过随机过程推导出来。

画一个正方形,并在该正方形内刻一个象限(半圆形的四分之一)(半径等于正方形边的象限,因此它尽可能多地填充正方形)

现在向正方形扔一枚飞镖,并记录它落在哪里——也就是说,在正方形内的任何地方随机选择一个点。当然,它落在正方形内,但它在半圆内吗?记录下这个事实。

重复这个过程很多次——你会发现半圆内的点数与投掷的总点数之比,将这个比率称为 x。

由于正方形的面积是 r 乘以 r,因此可以推断出半圆的面积是 x 乘以 r 乘以 r(即 x 乘以 r 的平方)。因此,x 乘以 4 会给你圆周率。

这不是一个快速使用的方法。但这是蒙特卡罗方法的一个很好的例子。如果你环顾四周,你可能会发现许多超出你计算技能的问题可以通过这些方法解决。

评论

2赞 Jeff Keslinke 2/3/2009
这是我们在学校的 java 项目中用来计算 Pi 的方法。只是使用随机器来得出 x,y 坐标,我们扔的“飞镖”越多,我们离 Pi 就越近。
223赞 nlucaroni 8/3/2008 #2

如前所述,蒙特卡罗方法应用了一些伟大的概念,但显然,它不是最快的,不是远景,也不是任何合理的衡量标准。此外,这完全取决于您正在寻找什么样的准确性。我所知道的最快的π是数字硬编码的那个。看看 Pi Pi[PDF],有很多公式。

这是一种快速收敛的方法——每次迭代大约 14 位数字。PiFast是目前最快的应用程序,它将此公式与FFT一起使用。我只写公式,因为代码很简单。这个公式几乎是拉马努金发现的,也是丘德诺夫斯基发现的。这实际上是他计算数十亿位数字的方式——所以这不是一个可以忽视的方法。该公式将很快溢出,并且由于我们正在除以阶乘,因此延迟此类计算以删除项将是有利的。

enter image description here

enter image description here

哪里

enter image description here

下面是 Brent-Salamin 算法。维基百科提到,当 a 和 b “足够接近”时,(a + b)² / 4t 将是 π 的近似值。我不确定“足够接近”是什么意思,但从我的测试来看,一次迭代得到了 2 位数字,两次迭代得到了 7 位数字,三次迭代得到了 15 位数字,当然这是双精度的,所以它可能会有基于其表示的错误,真正的计算可能更准确。

let pi_2 iters =
    let rec loop_ a b t p i =
        if i = 0 then a,b,t,p
        else
            let a_n = (a +. b) /. 2.0 
            and b_n = sqrt (a*.b)
            and p_n = 2.0 *. p in
            let t_n = t -. (p *. (a -. a_n) *. (a -. a_n)) in
            loop_ a_n b_n t_n p_n (i - 1)
    in 
    let a,b,t,p = loop_ (1.0) (1.0 /. (sqrt 2.0)) (1.0/.4.0) (1.0) iters in
    (a +. b) *. (a +. b) /. (4.0 *. t)

最后,一些圆周率高尔夫(800 位)怎么样?160个字符!

int a=10000,b,c=2800,d,e,f[2801],g;main(){for(;b-c;)f[b++]=a/5;for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a)for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);}

评论

1赞 Bill K 8/31/2010
假设您正在尝试自己实现第一个,sqr(k3) 不会有问题吗?我很确定它最终会变成一个你必须估计的无理数(IIRC,所有不是整数的根都是无理数)。如果你使用无限精度的算术,其他一切看起来都很简单,但平方根是一个交易破坏者。第二个也包括一个 sqrt。
3赞 Stephen 2/11/2011
根据我的经验,“足够接近”通常意味着涉及泰勒级数近似。
21赞 Michiel de Mare 8/7/2008 #3

如果“最快”是指最快键入代码,那么这里是 golfscript 解决方案:

;''6666,-2%{2+.2/@*\/10.3??2*+}*`1000<~\;
45赞 OysterD 8/25/2008 #4

实际上,有一整本书专门讨论计算 \pi 的快速方法:Jonathan 和 Peter Borwein 的“Pi and the AGM”(可在亚马逊上购买)。

我研究了 AGM 和相关算法:它非常有趣(尽管有时不平凡)。

请注意,要实现大多数现代算法来计算 \pi,您将需要一个多精度算术库(GMP 是一个相当不错的选择,尽管我上次使用它已经有一段时间了)。

最佳算法的时间复杂度以 O(M(n)log(n)) 为单位,其中 M(n) 是使用基于 FFT 的算法将两个 n 位整数相乘的时间复杂度 (M(n)=O(n log(n) log(log(n))),在计算 \pi 的数字时通常需要这种算法,并且这种算法在 GMP 中实现)。

请注意,尽管算法背后的数学可能不是微不足道的,但算法本身通常是几行伪代码,它们的实现通常非常简单(如果您选择不编写自己的多精度算术:-))。

28赞 Tyler 8/29/2008 #5

BBP 公式允许您计算第 n 位数字 - 以 2(或 16)为基数 - 甚至不必费心前 n-1 位数字 :)

127赞 Pat 9/2/2008 #6

我真的很喜欢这个程序,因为它通过查看自己的区域来近似π。

国际奥委会 1988 : westley.c

#define _ -F<00||--F-OO--;
int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
{
            _-_-_-_
       _-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
        _-_-_-_-_-_-_-_
            _-_-_-_
}

评论

1赞 Pat 9/25/2008
如果将 _ 替换为 -F<00||--F-OO-- 应该更容易理解 :-)
1赞 FryGuy 1/13/2009
或者,如果将 _ 替换为 “if (previous character is '-') { OO--; }F--;"
9赞 Chris Lutz 12/23/2009
这个程序在 1998 年很棒,但被破坏了,因为现代预处理器更自由地在宏扩展周围插入空格以防止这样的事情起作用。不幸的是,这是一个遗物。
41赞 Nietzche-jou 1/6/2010
传递给 cpp 以获取预期行为。--traditional-cpp
0赞 Petter Friberg 7/19/2017
@Pat,如果你觉得我编辑它的原因是因为我在 LQP 队列 stackoverflow.com/review/low-quality-posts/16750528 中看到了这个答案,因此为了避免删除,我在答案的链接中添加了代码。
17赞 Brad Gilbert 9/18/2008 #7

在编译时用 D 计算 PI。

( 复制自 DSource.org )

/** Calculate pi at compile time
 *
 * Compile with dmd -c pi.d
 */
module calcpi;

import meta.math;
import meta.conv;

/** real evaluateSeries!(real x, real metafunction!(real y, int n) term)
 *
 * Evaluate a power series at compile time.
 *
 * Given a metafunction of the form
 *  real term!(real y, int n),
 * which gives the nth term of a convergent series at the point y
 * (where the first term is n==1), and a real number x,
 * this metafunction calculates the infinite sum at the point x
 * by adding terms until the sum doesn't change any more.
 */
template evaluateSeries(real x, alias term, int n=1, real sumsofar=0.0)
{
  static if (n>1 && sumsofar == sumsofar + term!(x, n+1)) {
     const real evaluateSeries = sumsofar;
  } else {
     const real evaluateSeries = evaluateSeries!(x, term, n+1, sumsofar + term!(x, n));
  }
}

/*** Calculate atan(x) at compile time.
 *
 * Uses the Maclaurin formula
 *  atan(z) = z - z^3/3 + Z^5/5 - Z^7/7 + ...
 */
template atan(real z)
{
    const real atan = evaluateSeries!(z, atanTerm);
}

template atanTerm(real x, int n)
{
    const real atanTerm =  (n & 1 ? 1 : -1) * pow!(x, 2*n-1)/(2*n-1);
}

/// Machin's formula for pi
/// pi/4 = 4 atan(1/5) - atan(1/239).
pragma(msg, "PI = " ~ fcvt!(4.0 * (4*atan!(1/5.0) - atan!(1/239.0))) );

评论

3赞 Grant Johnson 9/26/2008
不幸的是,切线是反正切线,它基于 pi,这在某种程度上使这种计算无效。
24赞 Andrea Ambu 10/3/2008 #8

这是一种“经典”方法,非常容易实现。 python(不是最快的语言)中的这个实现做到了:

from math import pi
from time import time


precision = 10**6 # higher value -> higher precision
                  # lower  value -> higher speed

t = time()

calc = 0
for k in xrange(0, precision):
    calc += ((-1)**k) / (2*k+1.)
calc *= 4. # this is just a little optimization

t = time()-t

print "Calculated: %.40f" % calc
print "Constant pi: %.40f" % pi
print "Difference: %.40f" % abs(calc-pi)
print "Time elapsed: %s" % repr(t)

您可以在此处找到更多信息。

无论如何,在 python 中获取精确的 pi 值的最快方法是:

from gmpy import pi
print pi(3000) # the rule is the same as 
               # the precision on the previous code

这是 gmpy pi 方法的源代码,我认为在这种情况下,代码不如注释有用:

static char doc_pi[]="\
pi(n): returns pi with n bits of precision in an mpf object\n\
";

/* This function was originally from netlib, package bmp, by
 * Richard P. Brent. Paulo Cesar Pereira de Andrade converted
 * it to C and used it in his LISP interpreter.
 *
 * Original comments:
 * 
 *   sets mp pi = 3.14159... to the available precision.
 *   uses the gauss-legendre algorithm.
 *   this method requires time o(ln(t)m(t)), so it is slower
 *   than mppi if m(t) = o(t**2), but would be faster for
 *   large t if a faster multiplication algorithm were used
 *   (see comments in mpmul).
 *   for a description of the method, see - multiple-precision
 *   zero-finding and the complexity of elementary function
 *   evaluation (by r. p. brent), in analytic computational
 *   complexity (edited by j. f. traub), academic press, 1976, 151-176.
 *   rounding options not implemented, no guard digits used.
*/
static PyObject *
Pygmpy_pi(PyObject *self, PyObject *args)
{
    PympfObject *pi;
    int precision;
    mpf_t r_i2, r_i3, r_i4;
    mpf_t ix;

    ONE_ARG("pi", "i", &precision);
    if(!(pi = Pympf_new(precision))) {
        return NULL;
    }

    mpf_set_si(pi->f, 1);

    mpf_init(ix);
    mpf_set_ui(ix, 1);

    mpf_init2(r_i2, precision);

    mpf_init2(r_i3, precision);
    mpf_set_d(r_i3, 0.25);

    mpf_init2(r_i4, precision);
    mpf_set_d(r_i4, 0.5);
    mpf_sqrt(r_i4, r_i4);

    for (;;) {
        mpf_set(r_i2, pi->f);
        mpf_add(pi->f, pi->f, r_i4);
        mpf_div_ui(pi->f, pi->f, 2);
        mpf_mul(r_i4, r_i2, r_i4);
        mpf_sub(r_i2, pi->f, r_i2);
        mpf_mul(r_i2, r_i2, r_i2);
        mpf_mul(r_i2, r_i2, ix);
        mpf_sub(r_i3, r_i3, r_i2);
        mpf_sqrt(r_i4, r_i4);
        mpf_mul_ui(ix, ix, 2);
        /* Check for convergence */
        if (!(mpf_cmp_si(r_i2, 0) && 
              mpf_get_prec(r_i2) >= (unsigned)precision)) {
            mpf_mul(pi->f, pi->f, r_i4);
            mpf_div(pi->f, pi->f, r_i3);
            break;
        }
    }

    mpf_clear(ix);
    mpf_clear(r_i2);
    mpf_clear(r_i3);
    mpf_clear(r_i4);

    return (PyObject*)pi;
}

编辑:我在剪切、粘贴和缩进方面遇到了一些问题,你可以在这里找到源代码。

15赞 JosephStyons 1/13/2009 #9

这个版本(在 Delphi 中)没什么特别的,但它至少比 Nick Hodge :)在他的博客上发布的版本要快。在我的机器上,进行十亿次迭代大约需要 16 秒,给出的值为 3.14159265 25879(准确部分以粗体显示)。

program calcpi;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  start, finish: TDateTime;

function CalculatePi(iterations: integer): double;
var
  numerator, denominator, i: integer;
  sum: double;
begin
  {
  PI may be approximated with this formula:
  4 * (1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 .......)
  //}
  numerator := 1;
  denominator := 1;
  sum := 0;
  for i := 1 to iterations do begin
    sum := sum + (numerator/denominator);
    denominator := denominator + 2;
    numerator := -numerator;
  end;
  Result := 4 * sum;
end;

begin
  try
    start := Now;
    WriteLn(FloatToStr(CalculatePi(StrToInt(ParamStr(1)))));
    finish := Now;
    WriteLn('Seconds:' + FormatDateTime('hh:mm:ss.zz',finish-start));
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
13赞 Kristopher Johnson 2/21/2009 #10

在过去,由于字大小较小,浮点运算缓慢或不存在,我们曾经做过这样的事情:

/* Return approximation of n * PI; n is integer */
#define pi_times(n) (((n) * 22) / 7)

对于不需要太多精度的应用程序(例如视频游戏),这非常快并且足够准确。

评论

11赞 David Thornley 12/10/2009
为了更准确,请使用 .对于所涉及的数字大小非常准确。355 / 113
19赞 Jason Delife 2/27/2009 #11

圆周率正好是 3![弗林克教授(辛普森一家)]

开玩笑,但这里有一个 C# (.需要 NET-Framework)。

using System;
using System.Text;

class Program {
    static void Main(string[] args) {
        int Digits = 100;

        BigNumber x = new BigNumber(Digits);
        BigNumber y = new BigNumber(Digits);
        x.ArcTan(16, 5);
        y.ArcTan(4, 239);
        x.Subtract(y);
        string pi = x.ToString();
        Console.WriteLine(pi);
    }
}

public class BigNumber {
    private UInt32[] number;
    private int size;
    private int maxDigits;

    public BigNumber(int maxDigits) {
        this.maxDigits = maxDigits;
        this.size = (int)Math.Ceiling((float)maxDigits * 0.104) + 2;
        number = new UInt32[size];
    }
    public BigNumber(int maxDigits, UInt32 intPart)
        : this(maxDigits) {
        number[0] = intPart;
        for (int i = 1; i < size; i++) {
            number[i] = 0;
        }
    }
    private void VerifySameSize(BigNumber value) {
        if (Object.ReferenceEquals(this, value))
            throw new Exception("BigNumbers cannot operate on themselves");
        if (value.size != this.size)
            throw new Exception("BigNumbers must have the same size");
    }

    public void Add(BigNumber value) {
        VerifySameSize(value);

        int index = size - 1;
        while (index >= 0 && value.number[index] == 0)
            index--;

        UInt32 carry = 0;
        while (index >= 0) {
            UInt64 result = (UInt64)number[index] +
                            value.number[index] + carry;
            number[index] = (UInt32)result;
            if (result >= 0x100000000U)
                carry = 1;
            else
                carry = 0;
            index--;
        }
    }
    public void Subtract(BigNumber value) {
        VerifySameSize(value);

        int index = size - 1;
        while (index >= 0 && value.number[index] == 0)
            index--;

        UInt32 borrow = 0;
        while (index >= 0) {
            UInt64 result = 0x100000000U + (UInt64)number[index] -
                            value.number[index] - borrow;
            number[index] = (UInt32)result;
            if (result >= 0x100000000U)
                borrow = 0;
            else
                borrow = 1;
            index--;
        }
    }
    public void Multiply(UInt32 value) {
        int index = size - 1;
        while (index >= 0 && number[index] == 0)
            index--;

        UInt32 carry = 0;
        while (index >= 0) {
            UInt64 result = (UInt64)number[index] * value + carry;
            number[index] = (UInt32)result;
            carry = (UInt32)(result >> 32);
            index--;
        }
    }
    public void Divide(UInt32 value) {
        int index = 0;
        while (index < size && number[index] == 0)
            index++;

        UInt32 carry = 0;
        while (index < size) {
            UInt64 result = number[index] + ((UInt64)carry << 32);
            number[index] = (UInt32)(result / (UInt64)value);
            carry = (UInt32)(result % (UInt64)value);
            index++;
        }
    }
    public void Assign(BigNumber value) {
        VerifySameSize(value);
        for (int i = 0; i < size; i++) {
            number[i] = value.number[i];
        }
    }

    public override string ToString() {
        BigNumber temp = new BigNumber(maxDigits);
        temp.Assign(this);

        StringBuilder sb = new StringBuilder();
        sb.Append(temp.number[0]);
        sb.Append(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator);

        int digitCount = 0;
        while (digitCount < maxDigits) {
            temp.number[0] = 0;
            temp.Multiply(100000);
            sb.AppendFormat("{0:D5}", temp.number[0]);
            digitCount += 5;
        }

        return sb.ToString();
    }
    public bool IsZero() {
        foreach (UInt32 item in number) {
            if (item != 0)
                return false;
        }
        return true;
    }

    public void ArcTan(UInt32 multiplicand, UInt32 reciprocal) {
        BigNumber X = new BigNumber(maxDigits, multiplicand);
        X.Divide(reciprocal);
        reciprocal *= reciprocal;

        this.Assign(X);

        BigNumber term = new BigNumber(maxDigits);
        UInt32 divisor = 1;
        bool subtractTerm = true;
        while (true) {
            X.Divide(reciprocal);
            term.Assign(X);
            divisor += 2;
            term.Divide(divisor);
            if (term.IsZero())
                break;

            if (subtractTerm)
                this.Subtract(term);
            else
                this.Add(term);
            subtractTerm = !subtractTerm;
        }
    }
}
24赞 bob 3/8/2009 #12

我没有将 pi 定义为常量,而是总是使用 .acos(-1)

评论

2赞 C. K. Young 4/3/2009
cos(-1) 还是 acos(-1)?:-P这(后者)是我原始代码中的测试用例之一。它是我的首选之一(还有 atan2(0, -1),它实际上与 acos(-1) 相同,只是 acos 通常是根据 atan2 实现的),但一些编译器针对 4 * atan(1) 进行了优化!
19赞 Daniel C. Sobral 9/18/2009 #13

如果您愿意使用近似值,则适用于6位十进制数字,并且具有可用于整数表达式的额外优势。如今,这已经不那么重要了,因为“浮点数学协处理器”不再有任何意义,但它曾经非常重要。355 / 113

62赞 jon hanson 12/22/2009 #14

为了完整起见,C++ 模板版本,对于优化的构建,它将在编译时计算 PI 的近似值,并将内联到单个值。

#include <iostream>

template<int I>
struct sign
{
    enum {value = (I % 2) == 0 ? 1 : -1};
};

template<int I, int J>
struct pi_calc
{
    inline static double value ()
    {
        return (pi_calc<I-1, J>::value () + pi_calc<I-1, J+1>::value ()) / 2.0;
    }
};

template<int J>
struct pi_calc<0, J>
{
    inline static double value ()
    {
        return (sign<J>::value * 4.0) / (2.0 * J + 1.0) + pi_calc<0, J-1>::value ();
    }
};


template<>
struct pi_calc<0, 0>
{
    inline static double value ()
    {
        return 4.0;
    }
};

template<int I>
struct pi
{
    inline static double value ()
    {
        return pi_calc<I, I>::value ();
    }
};

int main ()
{
    std::cout.precision (12);

    const double pi_value = pi<10>::value ();

    std::cout << "pi ~ " << pi_value << std::endl;

    return 0;
}

请注意,对于 I > 10,优化的构建可能会很慢,对于非优化的运行也是如此。对于 12 次迭代,我相信大约有 80k 次调用 value()(在没有记忆的情况下)。

评论

0赞 maxwellb 6/30/2010
我运行这个并得到“pi ~ 3.14159265383”
5赞 jon hanson 6/30/2010
嗯,这精确到 9dp。你是在反对某事还是只是在观察?
0赞 Sebastião Miranda 4/4/2016
这里用于计算 PI 的算法的名称是什么?
1赞 jon hanson 4/4/2016
@sebastião-米兰达·莱布尼茨公式,平均加速度提高了收敛性。 根据公式计算每个连续项,非专业计算平均值。pi_calc<0, J>pi_calc<I, J>
13赞 Seth 12/23/2009 #15

如果要计算 π 值的近似值(出于某种原因),则应尝试二进制提取算法。BellardBBP 的改进给出了 O(N^2) 中的 PI。


如果要获取π值的近似值进行计算,则:

PI = 3.141592654

当然,这只是一个近似值,并不完全准确。它偏离了 0.000000000004102 多一点。(十万亿分之四,约4/10,000,000,000)。


如果你想用π做数学运算,那就给自己买一支铅笔和纸或一个计算机代数包,并使用π的确切值,π。

如果你真的想要一个公式,这个很有趣:

π = -i ln(-1)

评论

0赞 erikkallen 12/23/2009
公式取决于在复平面中如何定义 ln。它必须沿着复平面中的一条线不连续,并且该线是负实轴是很常见的。
18赞 qwerty01 2/28/2010 #16

带双打:

4.0 * (4.0 * Math.Atan(0.2) - Math.Atan(1.0 / 239.0))

这将精确到小数点后 14 位,足以填充双倍(不准确可能是因为弧切线中的其余小数被截断)。

还有 Seth,它是 3.141592653589793238463,而不是 64。

20赞 NihilistDandy 2/5/2011 #17

使用类似 Macin 的公式

176 * arctan (1/57) + 28 * arctan (1/239) - 48 * arctan (1/682) + 96 * arctan(1/12943) 

[; \left( 176 \arctan \frac{1}{57} + 28 \arctan \frac{1}{239} - 48 \arctan \frac{1}{682} + 96 \arctan \frac{1}{12943}\right) ;], for you TeX the World people.

在 Scheme 中实现,例如:

(+ (- (+ (* 176 (atan (/ 1 57))) (* 28 (atan (/ 1 239)))) (* 48 (atan (/ 1 682)))) (* 96 (atan (/ 1 12943))))

44赞 Tilo 10/28/2011 #18

下面准确地回答了如何以最快的方式做到这一点 - 以最少的计算工作量。即使你不喜欢这个答案,你也不得不承认,这确实是获得PI值的最快方法。

获取 Pi 值的最快方法是:

  1. 选择您喜欢的编程语言
  2. 加载其数学库
  3. 并发现 Pi 已经在那里定义了 -- 可以使用了!

如果您手头没有数学库..

第二快的方法(更通用的解决方案)是:

在互联网上查找 Pi,例如这里:

http://www.eveandersson.com/pi/digits/1000000(100 万位 .. 你的浮点精度是多少?

或在这里:

http://3.141592653589793238462643383279502884197169399375105820974944592.com/

或在这里:

http://en.wikipedia.org/wiki/Pi

找到您想要使用的任何精度算术所需的数字非常快,并且通过定义一个常量,您可以确保不会浪费宝贵的 CPU 时间。

这不仅是一个部分幽默的答案,而且在现实中,如果有人愿意继续计算 Pi 在实际应用程序中的价值......这将是对 CPU 时间的极大浪费,不是吗?至少我没有看到尝试重新计算它的真正应用程序。

还要考虑到 NASA 仅使用 Pi 的 15 位数字来计算星际旅行:

评论

1赞 Max 5/14/2020
亲爱的Tilo:请注意,OP说:“我正在寻找获得π价值的最快方法,作为个人挑战。更具体地说,我使用的方法不涉及使用 #define 常量(如 M_PI)或对数字进行硬编码
4赞 Tilo 5/14/2020
亲爱的@Max:请注意,OP在我回答编辑了他们的原始问题 - 这几乎不是我的错;)我的解决方案仍然是最快的方法,并且以任何所需的浮点精度解决问题,并且没有 CPU 周期优雅地:)
1赞 Max 5/14/2020
哦,对不起,我没有意识到。只是一个想法,硬编码常量的精度不会低于计算 pi 的精度吗?我想这取决于它是什么语言以及创建者愿意将所有数字放入 :-)
0赞 Yin Cognyto 5/11/2022
我意识到你以最诚实和最有趣的方式回答了这个问题,但我也意识到有很多人认真对待它并将这个想法作为一种生活方式——对此的赞成票数量证明了这一点:不要做任何事情来使用你的大脑,因为别人已经、正在或将要为你做这件事。毕竟,人们已经通过手机向朋友发送了已经制作的生日祝福,因为他们无法想出几个原创词来表达......
0赞 Tilo 5/15/2022
vm.tiktok.com/ZTdsuAWQK/?k=1
1赞 Agnius Vasiliauskas 6/4/2017 #19

从圆面积计算π:-)

<input id="range" type="range" min="10" max="960" value="10" step="50" oninput="calcPi()">
<br>
<div id="cont"></div>

<script>
function generateCircle(width) {
    var c = width/2;
    var delta = 1.0;
    var str = "";
    var xCount = 0;
    for (var x=0; x <= width; x++) {
        for (var y = 0; y <= width; y++) {
            var d = Math.sqrt((x-c)*(x-c) + (y-c)*(y-c));
            if (d > (width-1)/2) {
                str += '.';
            }
            else {
                xCount++;
                str += 'o';
            }
            str += "&nbsp;" 
        }
        str += "\n";
    }
    var pi = (xCount * 4) / (width * width);
    return [str, pi];
}

function calcPi() {
    var e = document.getElementById("cont");
    var width = document.getElementById("range").value;
    e.innerHTML = "<h4>Generating circle...</h4>";
    setTimeout(function() {
        var circ = generateCircle(width);
        e.innerHTML  = "<pre>" + "π = " + circ[1].toFixed(2) + "\n" + circ[0] +"</pre>";
    }, 200);
}
calcPi();
</script>

1赞 paperclip optimizer 5/8/2020 #20

如果您不介意执行平方根和几个逆运算,Chudnovsky 算法非常快。它在短短 2 次迭代中收敛到双精度。

/*
    Chudnovsky algorithm for computing PI
*/

#include <iostream>
#include <cmath>
using namespace std;

double calc_PI(int K=2) {

    static const int A = 545140134;
    static const int B = 13591409;
    static const int D = 640320;

    const double ID3 = 1./ (double(D)*double(D)*double(D));

    double sum = 0.;
    double b   = sqrt(ID3);
    long long int p = 1;
    long long int a = B;

    sum += double(p) * double(a)* b;

    // 2 iterations enough for double convergence
    for (int k=1; k<K; ++k) {
        // A*k + B
        a += A;
        // update denominator
        b *= ID3;
        // p = (-1)^k 6k! / 3k! k!^3
        p *= (6*k)*(6*k-1)*(6*k-2)*(6*k-3)*(6*k-4)*(6*k-5);
        p /= (3*k)*(3*k-1)*(3*k-2) * k*k*k;
        p = -p;

        sum += double(p) * double(a)* b;
    }

    return 1./(12*sum);
}

int main() {

    cout.precision(16);
    cout.setf(ios::fixed);

    for (int k=1; k<=5; ++k) cout << "k = " << k << "   PI = " << calc_PI(k) << endl;

    return 0;
}

结果:

k = 1   PI = 3.1415926535897341
k = 2   PI = 3.1415926535897931
k = 3   PI = 3.1415926535897931
k = 4   PI = 3.1415926535897931
k = 5   PI = 3.1415926535897931
2赞 user14273431 10/18/2020 #21

基本上是回形针优化器的 C 版本的答案,而且更加简化:

#include <stdio.h>
#include <math.h>

double calc_PI(int K) {
    static const int A = 545140134;
    static const int B = 13591409;
    static const int D = 640320;
    const double ID3 = 1.0 / ((double) D * (double) D * (double) D);
    double sum = 0.0;
    double b = sqrt(ID3);
    long long int p = 1;
    long long int a = B;
    sum += (double) p * (double) a * b;
    for (int k = 1; k < K; ++k) {
        a += A;
        b *= ID3;
        p *= (6 * k) * (6 * k - 1) * (6 * k - 2) * (6 * k - 3) * (6 * k - 4) * (6 * k - 5);
        p /= (3 * k) * (3 * k - 1) * (3 * k - 2) * k * k * k;
        p = -p;
        sum += (double) p * (double) a * b;
    }
    return 1.0 / (12 * sum);
}

int main() {
    for (int k = 1; k <= 5; ++k) {
        printf("k = %i, PI = %.16f\n", k, calc_PI(k));
    }
}

但为了进一步简化,这个算法采用了 Chudnovsky 的公式,如果你不真正理解代码,我可以完全简化它。

摘要:我们将得到一个从 1 到 5 的数字,并将其添加到我们将用于获取 PI 的函数中。然后给你 3 个数字:545140134 (A)、13591409 (B)、640320 (D)。然后我们将使用 D 作为自身乘以 3 倍到另一个 (ID3)。然后我们将 ID3 的平方根放入另一个 (b) 并分配 2 个数字:1 (p),B (a) 的值。请注意,C 不区分大小写。然后,通过将 p、a 和 b 的值相乘来创建一个(总和),这些值都在 s 中。然后一个循环,直到为函数给出的数字将开始并将 A 的值与 a 相加,b 的值乘以 ID3,p 的值将乘以我希望你能理解的多个值,并且也被多个值除以。总和将再次乘以 p、a 和 b,循环将重复,直到循环数的值大于或等于 5。稍后,总和乘以 12 并由函数返回,得到 PI 的结果。doubledoubledoubledoubledouble

好吧,那很长,但我想你会明白的......

1赞 Rajanand 10/18/2021 #22

我认为圆周率的值是圆的周长和半径之间的比率。

它可以通过常规的数学计算简单地实现

0赞 Andy Richter 9/20/2022 #23

比 GMPY2 和 MPmath 内置更快:45 分钟内达到 10 亿:


我尝试了几种方法;Manchin、AGM 和 Chudnovsky Bros. Chudnovsky 与 Binary Split 是最快的: 我的github :
https://github.com/Overboard-code/Pi-Pourri

我的二进制拆分 Chudnovsky 的速度大约是内置 gmpy2.const_pi() 的两。MPmath.mp.pi() 花了 50 分钟才能获得 10 亿,所以它几乎和 Chudnovsky 一样快。

我也非常感谢性能提示。我不确定我的代码是否完美。它是 100% 准确的(所有公式都同意 1 亿),但也许可以更快?

我尝试将 gmpy2.const_pi() 增加到 1 亿位,在同一台机器上花了 300 秒,而 Chudnovsky 需要 150 秒。pi.txt 和 pi2.txt 是相同的。

我在不到一个小时的时间内在我的旧 i7 16GB 笔记本电脑上达到了 10 亿位数字。

以下是我尝试过的 12 种方法中最快的一种:

class PiChudnovsky:
    """Version of Chudnovsky Bros using Binary Splitting 
        So far this is the winner for fastest time to a million digits on my older intel i7
    """
    A = mpz(13591409)
    B = mpz(545140134)
    C = mpz(640320)
    D = mpz(426880)
    E = mpz(10005)
    C3_24  = pow(C, mpz(3)) // mpz(24)
    #DIGITS_PER_TERM = math.log(53360 ** 3) / math.log(10)  #=> 14.181647462725476
    DIGITS_PER_TERM = 14.181647462725476
    MMILL = mpz(1000000)

    def __init__(self,ndigits):
        """ Initialization
        :param int ndigits: digits of PI computation
        """
        self.ndigits = ndigits
        self.n      = mpz(self.ndigits // self.DIGITS_PER_TERM + 1)
        self.prec   = mpz((self.ndigits + 1) * LOG2_10)
        self.one_sq = pow(mpz(10),mpz(2 * ndigits))
        self.sqrt_c = isqrt(self.E * self.one_sq)
        self.iters  = mpz(0)
        self.start_time = 0

    def compute(self):
        """ Computation """
        try:
            self.start_time = time.time()
            logging.debug("Starting {} formula to {:,} decimal places"
                .format(name,ndigits) )
            __, q, t = self.__bs(mpz(0), self.n)  # p is just for recursion
            pi = (q * self.D * self.sqrt_c) // t
            logging.debug('{} calulation Done! {:,} iterations and {:.2f} seconds.'
                .format( name, int(self.iters),time.time() - self.start_time))
            get_context().precision= int((self.ndigits+10) * LOG2_10)
            pi_s = pi.digits() # digits() gmpy2 creates a string 
            pi_o = pi_s[:1] + "." + pi_s[1:]
            return pi_o,int(self.iters),time.time() - self.start_time
        except Exception as e:
            print (e.message, e.args)
            raise

    def __bs(self, a, b):
        """ PQT computation by BSA(= Binary Splitting Algorithm)
        :param int a: positive integer
        :param int b: positive integer
        :return list [int p_ab, int q_ab, int t_ab]
        """
        try:
            self.iters += mpz(1)
            if self.iters % self.MMILL  == mpz(0):
                logging.debug('Chudnovsky ... {:,} iterations and {:.2f} seconds.'
                    .format( int(self.iters),time.time() - self.start_time))
            if a + mpz(1) == b:
                if a == mpz(0):
                    p_ab = q_ab = mpz(1)
                else:
                    p_ab = mpz((mpz(6) * a - mpz(5)) * (mpz(2) * a - mpz(1)) * (mpz(6) * a - mpz(1)))
                    q_ab = pow(a,mpz(3)) * self.C3_24
                t_ab = p_ab * (self.A + self.B * a)
                if a & 1:
                    t_ab *= mpz(-1)
            else:
                m = (a + b) // mpz(2)
                p_am, q_am, t_am = self.__bs(a, m)
                p_mb, q_mb, t_mb = self.__bs(m, b)
                p_ab = p_am * p_mb
                q_ab = q_am * q_mb
                t_ab = q_mb * t_am + p_am * t_mb
            return [p_ab, q_ab, t_ab]
        except Exception as e:
            print (e.message, e.args)
            raise

以下是 1,000,000,000 位不到 45 分钟的输出:

python pi-pourri.py -v -d 1,000,000,000 -a 10 

[INFO] 2022-10-03 09:22:51,860 <module>: MainProcess Computing π to 1,000,000,000 digits.
[DEBUG] 2022-10-03 09:25:00,543 compute: MainProcess Starting   Chudnovsky brothers  1988 
    π = (Q(0, N) / 12T(0, N) + 12AQ(0, N))**(C**(3/2))
 formula to 1,000,000,000 decimal places
[DEBUG] 2022-10-03 09:25:04,995 __bs: MainProcess Chudnovsky ... 1,000,000 iterations and 4.45 seconds.
[DEBUG] 2022-10-03 09:25:10,836 __bs: MainProcess Chudnovsky ... 2,000,000 iterations and 10.29 seconds.
[DEBUG] 2022-10-03 09:25:18,227 __bs: MainProcess Chudnovsky ... 3,000,000 iterations and 17.68 seconds.
[DEBUG] 2022-10-03 09:25:24,512 __bs: MainProcess Chudnovsky ... 4,000,000 iterations and 23.97 seconds.
[DEBUG] 2022-10-03 09:25:35,670 __bs: MainProcess Chudnovsky ... 5,000,000 iterations and 35.13 seconds.
[DEBUG] 2022-10-03 09:25:41,376 __bs: MainProcess Chudnovsky ... 6,000,000 iterations and 40.83 seconds.
[DEBUG] 2022-10-03 09:25:49,238 __bs: MainProcess Chudnovsky ... 7,000,000 iterations and 48.69 seconds.
[DEBUG] 2022-10-03 09:25:55,646 __bs: MainProcess Chudnovsky ... 8,000,000 iterations and 55.10 seconds.
[DEBUG] 2022-10-03 09:26:15,043 __bs: MainProcess Chudnovsky ... 9,000,000 iterations and 74.50 seconds.
[DEBUG] 2022-10-03 09:26:21,437 __bs: MainProcess Chudnovsky ... 10,000,000 iterations and 80.89 seconds.
[DEBUG] 2022-10-03 09:26:26,587 __bs: MainProcess Chudnovsky ... 11,000,000 iterations and 86.04 seconds.
[DEBUG] 2022-10-03 09:26:34,777 __bs: MainProcess Chudnovsky ... 12,000,000 iterations and 94.23 seconds.
[DEBUG] 2022-10-03 09:26:41,231 __bs: MainProcess Chudnovsky ... 13,000,000 iterations and 100.69 seconds.
[DEBUG] 2022-10-03 09:26:52,972 __bs: MainProcess Chudnovsky ... 14,000,000 iterations and 112.43 seconds.
[DEBUG] 2022-10-03 09:26:59,517 __bs: MainProcess Chudnovsky ... 15,000,000 iterations and 118.97 seconds.
[DEBUG] 2022-10-03 09:27:07,932 __bs: MainProcess Chudnovsky ... 16,000,000 iterations and 127.39 seconds.
[DEBUG] 2022-10-03 09:27:14,036 __bs: MainProcess Chudnovsky ... 17,000,000 iterations and 133.49 seconds.
[DEBUG] 2022-10-03 09:27:51,629 __bs: MainProcess Chudnovsky ... 18,000,000 iterations and 171.09 seconds.
[DEBUG] 2022-10-03 09:27:58,176 __bs: MainProcess Chudnovsky ... 19,000,000 iterations and 177.63 seconds.
[DEBUG] 2022-10-03 09:28:06,704 __bs: MainProcess Chudnovsky ... 20,000,000 iterations and 186.16 seconds.
[DEBUG] 2022-10-03 09:28:13,376 __bs: MainProcess Chudnovsky ... 21,000,000 iterations and 192.83 seconds.
[DEBUG] 2022-10-03 09:28:18,737 __bs: MainProcess Chudnovsky ... 22,000,000 iterations and 198.19 seconds.
[DEBUG] 2022-10-03 09:28:31,095 __bs: MainProcess Chudnovsky ... 23,000,000 iterations and 210.55 seconds.
[DEBUG] 2022-10-03 09:28:37,789 __bs: MainProcess Chudnovsky ... 24,000,000 iterations and 217.25 seconds.
[DEBUG] 2022-10-03 09:28:46,171 __bs: MainProcess Chudnovsky ... 25,000,000 iterations and 225.63 seconds.
[DEBUG] 2022-10-03 09:28:52,933 __bs: MainProcess Chudnovsky ... 26,000,000 iterations and 232.39 seconds.
[DEBUG] 2022-10-03 09:29:13,524 __bs: MainProcess Chudnovsky ... 27,000,000 iterations and 252.98 seconds.
[DEBUG] 2022-10-03 09:29:19,676 __bs: MainProcess Chudnovsky ... 28,000,000 iterations and 259.13 seconds.
[DEBUG] 2022-10-03 09:29:28,196 __bs: MainProcess Chudnovsky ... 29,000,000 iterations and 267.65 seconds.
[DEBUG] 2022-10-03 09:29:34,720 __bs: MainProcess Chudnovsky ... 30,000,000 iterations and 274.18 seconds.
[DEBUG] 2022-10-03 09:29:47,075 __bs: MainProcess Chudnovsky ... 31,000,000 iterations and 286.53 seconds.
[DEBUG] 2022-10-03 09:29:53,746 __bs: MainProcess Chudnovsky ... 32,000,000 iterations and 293.20 seconds.
[DEBUG] 2022-10-03 09:29:59,099 __bs: MainProcess Chudnovsky ... 33,000,000 iterations and 298.56 seconds.
[DEBUG] 2022-10-03 09:30:07,511 __bs: MainProcess Chudnovsky ... 34,000,000 iterations and 306.97 seconds.
[DEBUG] 2022-10-03 09:30:14,279 __bs: MainProcess Chudnovsky ... 35,000,000 iterations and 313.74 seconds.
[DEBUG] 2022-10-03 09:31:31,710 __bs: MainProcess Chudnovsky ... 36,000,000 iterations and 391.17 seconds.
[DEBUG] 2022-10-03 09:31:38,454 __bs: MainProcess Chudnovsky ... 37,000,000 iterations and 397.91 seconds.
[DEBUG] 2022-10-03 09:31:46,437 __bs: MainProcess Chudnovsky ... 38,000,000 iterations and 405.89 seconds.
[DEBUG] 2022-10-03 09:31:53,285 __bs: MainProcess Chudnovsky ... 39,000,000 iterations and 412.74 seconds.
[DEBUG] 2022-10-03 09:32:05,602 __bs: MainProcess Chudnovsky ... 40,000,000 iterations and 425.06 seconds.
[DEBUG] 2022-10-03 09:32:12,220 __bs: MainProcess Chudnovsky ... 41,000,000 iterations and 431.68 seconds.
[DEBUG] 2022-10-03 09:32:20,708 __bs: MainProcess Chudnovsky ... 42,000,000 iterations and 440.17 seconds.
[DEBUG] 2022-10-03 09:32:27,552 __bs: MainProcess Chudnovsky ... 43,000,000 iterations and 447.01 seconds.
[DEBUG] 2022-10-03 09:32:32,986 __bs: MainProcess Chudnovsky ... 44,000,000 iterations and 452.44 seconds.
[DEBUG] 2022-10-03 09:32:53,904 __bs: MainProcess Chudnovsky ... 45,000,000 iterations and 473.36 seconds.
[DEBUG] 2022-10-03 09:33:00,832 __bs: MainProcess Chudnovsky ... 46,000,000 iterations and 480.29 seconds.
[DEBUG] 2022-10-03 09:33:09,198 __bs: MainProcess Chudnovsky ... 47,000,000 iterations and 488.66 seconds.
[DEBUG] 2022-10-03 09:33:16,000 __bs: MainProcess Chudnovsky ... 48,000,000 iterations and 495.46 seconds.
[DEBUG] 2022-10-03 09:33:27,921 __bs: MainProcess Chudnovsky ... 49,000,000 iterations and 507.38 seconds.
[DEBUG] 2022-10-03 09:33:34,778 __bs: MainProcess Chudnovsky ... 50,000,000 iterations and 514.24 seconds.
[DEBUG] 2022-10-03 09:33:43,298 __bs: MainProcess Chudnovsky ... 51,000,000 iterations and 522.76 seconds.
[DEBUG] 2022-10-03 09:33:49,959 __bs: MainProcess Chudnovsky ... 52,000,000 iterations and 529.42 seconds.
[DEBUG] 2022-10-03 09:34:29,294 __bs: MainProcess Chudnovsky ... 53,000,000 iterations and 568.75 seconds.
[DEBUG] 2022-10-03 09:34:36,176 __bs: MainProcess Chudnovsky ... 54,000,000 iterations and 575.63 seconds.
[DEBUG] 2022-10-03 09:34:41,576 __bs: MainProcess Chudnovsky ... 55,000,000 iterations and 581.03 seconds.
[DEBUG] 2022-10-03 09:34:50,161 __bs: MainProcess Chudnovsky ... 56,000,000 iterations and 589.62 seconds.
[DEBUG] 2022-10-03 09:34:56,811 __bs: MainProcess Chudnovsky ... 57,000,000 iterations and 596.27 seconds.
[DEBUG] 2022-10-03 09:35:09,382 __bs: MainProcess Chudnovsky ... 58,000,000 iterations and 608.84 seconds.
[DEBUG] 2022-10-03 09:35:16,206 __bs: MainProcess Chudnovsky ... 59,000,000 iterations and 615.66 seconds.
[DEBUG] 2022-10-03 09:35:24,295 __bs: MainProcess Chudnovsky ... 60,000,000 iterations and 623.75 seconds.
[DEBUG] 2022-10-03 09:35:31,095 __bs: MainProcess Chudnovsky ... 61,000,000 iterations and 630.55 seconds.
[DEBUG] 2022-10-03 09:35:52,139 __bs: MainProcess Chudnovsky ... 62,000,000 iterations and 651.60 seconds.
[DEBUG] 2022-10-03 09:35:58,781 __bs: MainProcess Chudnovsky ... 63,000,000 iterations and 658.24 seconds.
[DEBUG] 2022-10-03 09:36:07,399 __bs: MainProcess Chudnovsky ... 64,000,000 iterations and 666.86 seconds.
[DEBUG] 2022-10-03 09:36:12,847 __bs: MainProcess Chudnovsky ... 65,000,000 iterations and 672.30 seconds.
[DEBUG] 2022-10-03 09:36:19,763 __bs: MainProcess Chudnovsky ... 66,000,000 iterations and 679.22 seconds.
[DEBUG] 2022-10-03 09:36:32,351 __bs: MainProcess Chudnovsky ... 67,000,000 iterations and 691.81 seconds.
[DEBUG] 2022-10-03 09:36:39,078 __bs: MainProcess Chudnovsky ... 68,000,000 iterations and 698.53 seconds.
[DEBUG] 2022-10-03 09:36:47,830 __bs: MainProcess Chudnovsky ... 69,000,000 iterations and 707.29 seconds.
[DEBUG] 2022-10-03 09:36:54,701 __bs: MainProcess Chudnovsky ... 70,000,000 iterations and 714.16 seconds.
[DEBUG] 2022-10-03 09:39:39,357 __bs: MainProcess Chudnovsky ... 71,000,000 iterations and 878.81 seconds.
[DEBUG] 2022-10-03 09:39:46,199 __bs: MainProcess Chudnovsky ... 72,000,000 iterations and 885.66 seconds.
[DEBUG] 2022-10-03 09:39:54,956 __bs: MainProcess Chudnovsky ... 73,000,000 iterations and 894.41 seconds.
[DEBUG] 2022-10-03 09:40:01,639 __bs: MainProcess Chudnovsky ... 74,000,000 iterations and 901.10 seconds.
[DEBUG] 2022-10-03 09:40:14,219 __bs: MainProcess Chudnovsky ... 75,000,000 iterations and 913.68 seconds.
[DEBUG] 2022-10-03 09:40:19,680 __bs: MainProcess Chudnovsky ... 76,000,000 iterations and 919.14 seconds.
[DEBUG] 2022-10-03 09:40:26,625 __bs: MainProcess Chudnovsky ... 77,000,000 iterations and 926.08 seconds.
[DEBUG] 2022-10-03 09:40:35,212 __bs: MainProcess Chudnovsky ... 78,000,000 iterations and 934.67 seconds.
[DEBUG] 2022-10-03 09:40:41,914 __bs: MainProcess Chudnovsky ... 79,000,000 iterations and 941.37 seconds.
[DEBUG] 2022-10-03 09:41:03,218 __bs: MainProcess Chudnovsky ... 80,000,000 iterations and 962.68 seconds.
[DEBUG] 2022-10-03 09:41:10,213 __bs: MainProcess Chudnovsky ... 81,000,000 iterations and 969.67 seconds.
[DEBUG] 2022-10-03 09:41:18,344 __bs: MainProcess Chudnovsky ... 82,000,000 iterations and 977.80 seconds.
[DEBUG] 2022-10-03 09:41:25,261 __bs: MainProcess Chudnovsky ... 83,000,000 iterations and 984.72 seconds.
[DEBUG] 2022-10-03 09:41:37,663 __bs: MainProcess Chudnovsky ... 84,000,000 iterations and 997.12 seconds.
[DEBUG] 2022-10-03 09:41:44,680 __bs: MainProcess Chudnovsky ... 85,000,000 iterations and 1004.14 seconds.
[DEBUG] 2022-10-03 09:41:53,411 __bs: MainProcess Chudnovsky ... 86,000,000 iterations and 1012.87 seconds.
[DEBUG] 2022-10-03 09:41:58,926 __bs: MainProcess Chudnovsky ... 87,000,000 iterations and 1018.38 seconds.
[DEBUG] 2022-10-03 09:42:05,858 __bs: MainProcess Chudnovsky ... 88,000,000 iterations and 1025.32 seconds.
[DEBUG] 2022-10-03 09:42:46,163 __bs: MainProcess Chudnovsky ... 89,000,000 iterations and 1065.62 seconds.
[DEBUG] 2022-10-03 09:42:53,054 __bs: MainProcess Chudnovsky ... 90,000,000 iterations and 1072.51 seconds.
[DEBUG] 2022-10-03 09:43:02,030 __bs: MainProcess Chudnovsky ... 91,000,000 iterations and 1081.49 seconds.
[DEBUG] 2022-10-03 09:43:09,192 __bs: MainProcess Chudnovsky ... 92,000,000 iterations and 1088.65 seconds.
[DEBUG] 2022-10-03 09:43:21,533 __bs: MainProcess Chudnovsky ... 93,000,000 iterations and 1100.99 seconds.
[DEBUG] 2022-10-03 09:43:28,643 __bs: MainProcess Chudnovsky ... 94,000,000 iterations and 1108.10 seconds.
[DEBUG] 2022-10-03 09:43:37,372 __bs: MainProcess Chudnovsky ... 95,000,000 iterations and 1116.83 seconds.
[DEBUG] 2022-10-03 09:43:44,558 __bs: MainProcess Chudnovsky ... 96,000,000 iterations and 1124.02 seconds.
[DEBUG] 2022-10-03 09:44:06,555 __bs: MainProcess Chudnovsky ... 97,000,000 iterations and 1146.01 seconds.
[DEBUG] 2022-10-03 09:44:12,220 __bs: MainProcess Chudnovsky ... 98,000,000 iterations and 1151.68 seconds.
[DEBUG] 2022-10-03 09:44:19,278 __bs: MainProcess Chudnovsky ... 99,000,000 iterations and 1158.74 seconds.
[DEBUG] 2022-10-03 09:44:28,323 __bs: MainProcess Chudnovsky ... 100,000,000 iterations and 1167.78 seconds.
[DEBUG] 2022-10-03 09:44:35,211 __bs: MainProcess Chudnovsky ... 101,000,000 iterations and 1174.67 seconds.
[DEBUG] 2022-10-03 09:44:48,331 __bs: MainProcess Chudnovsky ... 102,000,000 iterations and 1187.79 seconds.
[DEBUG] 2022-10-03 09:44:54,835 __bs: MainProcess Chudnovsky ... 103,000,000 iterations and 1194.29 seconds.
[DEBUG] 2022-10-03 09:45:03,869 __bs: MainProcess Chudnovsky ... 104,000,000 iterations and 1203.33 seconds.
[DEBUG] 2022-10-03 09:45:10,967 __bs: MainProcess Chudnovsky ... 105,000,000 iterations and 1210.42 seconds.
[DEBUG] 2022-10-03 09:46:32,760 __bs: MainProcess Chudnovsky ... 106,000,000 iterations and 1292.22 seconds.
[DEBUG] 2022-10-03 09:46:39,872 __bs: MainProcess Chudnovsky ... 107,000,000 iterations and 1299.33 seconds.
[DEBUG] 2022-10-03 09:46:48,948 __bs: MainProcess Chudnovsky ... 108,000,000 iterations and 1308.41 seconds.
[DEBUG] 2022-10-03 09:46:54,611 __bs: MainProcess Chudnovsky ... 109,000,000 iterations and 1314.07 seconds.
[DEBUG] 2022-10-03 09:47:01,727 __bs: MainProcess Chudnovsky ... 110,000,000 iterations and 1321.18 seconds.
[DEBUG] 2022-10-03 09:47:14,525 __bs: MainProcess Chudnovsky ... 111,000,000 iterations and 1333.98 seconds.
[DEBUG] 2022-10-03 09:47:21,682 __bs: MainProcess Chudnovsky ... 112,000,000 iterations and 1341.14 seconds.
[DEBUG] 2022-10-03 09:47:30,610 __bs: MainProcess Chudnovsky ... 113,000,000 iterations and 1350.07 seconds.
[DEBUG] 2022-10-03 09:47:37,176 __bs: MainProcess Chudnovsky ... 114,000,000 iterations and 1356.63 seconds.
[DEBUG] 2022-10-03 09:47:59,642 __bs: MainProcess Chudnovsky ... 115,000,000 iterations and 1379.10 seconds.
[DEBUG] 2022-10-03 09:48:06,702 __bs: MainProcess Chudnovsky ... 116,000,000 iterations and 1386.16 seconds.
[DEBUG] 2022-10-03 09:48:15,483 __bs: MainProcess Chudnovsky ... 117,000,000 iterations and 1394.94 seconds.
[DEBUG] 2022-10-03 09:48:22,537 __bs: MainProcess Chudnovsky ... 118,000,000 iterations and 1401.99 seconds.
[DEBUG] 2022-10-03 09:48:35,714 __bs: MainProcess Chudnovsky ... 119,000,000 iterations and 1415.17 seconds.
[DEBUG] 2022-10-03 09:48:41,321 __bs: MainProcess Chudnovsky ... 120,000,000 iterations and 1420.78 seconds.
[DEBUG] 2022-10-03 09:48:48,408 __bs: MainProcess Chudnovsky ... 121,000,000 iterations and 1427.87 seconds.
[DEBUG] 2022-10-03 09:48:57,138 __bs: MainProcess Chudnovsky ... 122,000,000 iterations and 1436.60 seconds.
[DEBUG] 2022-10-03 09:49:04,328 __bs: MainProcess Chudnovsky ... 123,000,000 iterations and 1443.79 seconds.
[DEBUG] 2022-10-03 09:49:46,274 __bs: MainProcess Chudnovsky ... 124,000,000 iterations and 1485.73 seconds.
[DEBUG] 2022-10-03 09:49:52,833 __bs: MainProcess Chudnovsky ... 125,000,000 iterations and 1492.29 seconds.
[DEBUG] 2022-10-03 09:50:01,786 __bs: MainProcess Chudnovsky ... 126,000,000 iterations and 1501.24 seconds.
[DEBUG] 2022-10-03 09:50:08,975 __bs: MainProcess Chudnovsky ... 127,000,000 iterations and 1508.43 seconds.
[DEBUG] 2022-10-03 09:50:21,850 __bs: MainProcess Chudnovsky ... 128,000,000 iterations and 1521.31 seconds.
[DEBUG] 2022-10-03 09:50:28,962 __bs: MainProcess Chudnovsky ... 129,000,000 iterations and 1528.42 seconds.
[DEBUG] 2022-10-03 09:50:34,594 __bs: MainProcess Chudnovsky ... 130,000,000 iterations and 1534.05 seconds.
[DEBUG] 2022-10-03 09:50:43,647 __bs: MainProcess Chudnovsky ... 131,000,000 iterations and 1543.10 seconds.
[DEBUG] 2022-10-03 09:50:50,724 __bs: MainProcess Chudnovsky ... 132,000,000 iterations and 1550.18 seconds.
[DEBUG] 2022-10-03 09:51:12,742 __bs: MainProcess Chudnovsky ... 133,000,000 iterations and 1572.20 seconds.
[DEBUG] 2022-10-03 09:51:19,799 __bs: MainProcess Chudnovsky ... 134,000,000 iterations and 1579.26 seconds.
[DEBUG] 2022-10-03 09:51:28,824 __bs: MainProcess Chudnovsky ... 135,000,000 iterations and 1588.28 seconds.
[DEBUG] 2022-10-03 09:51:35,324 __bs: MainProcess Chudnovsky ... 136,000,000 iterations and 1594.78 seconds.
[DEBUG] 2022-10-03 09:51:48,419 __bs: MainProcess Chudnovsky ... 137,000,000 iterations and 1607.88 seconds.
[DEBUG] 2022-10-03 09:51:55,634 __bs: MainProcess Chudnovsky ... 138,000,000 iterations and 1615.09 seconds.
[DEBUG] 2022-10-03 09:52:04,435 __bs: MainProcess Chudnovsky ... 139,000,000 iterations and 1623.89 seconds.
[DEBUG] 2022-10-03 09:52:11,583 __bs: MainProcess Chudnovsky ... 140,000,000 iterations and 1631.04 seconds.
[DEBUG] 2022-10-03 09:52:17,222 __bs: MainProcess Chudnovsky ... 141,000,000 iterations and 1636.68 seconds.
[DEBUG] 2022-10-03 10:02:43,939 compute: MainProcess    Chudnovsky brothers  1988 
    π = (Q(0, N) / 12T(0, N) + 12AQ(0, N))**(C**(3/2))
 calulation Done! 141,027,339 iterations and 2263.39 seconds.
[INFO] 2022-10-03 10:09:07,119 <module>: MainProcess Last 5 digits of π were 45519 as expected at offset 999,999,995
[INFO] 2022-10-03 10:09:07,119 <module>: MainProcess Calculated π to 1,000,000,000 digits using a formula of:
 10     Chudnovsky brothers  1988 
    π = (Q(0, N) / 12T(0, N) + 12AQ(0, N))**(C**(3/2))
 
[INFO] 2022-10-03 10:09:07,120 <module>: MainProcess Calculation took 141,027,339 iterations and 0:44:06.398345.

math_pi.pi(b = 1000000) 更快到一百万。快了大约 40 倍。但它不能达到十亿。100万是最多的数字。

GMPY 内置的 GMPY 如下所示:

python pi-pourri.py -v -d 1,000,000,000 -a 11
[INFO] 2022-10-03 14:33:34,729 <module>: MainProcess Computing π to 1,000,000,000 digits.
[DEBUG] 2022-10-03 14:33:34,729 compute: MainProcess Starting   const_pi() function from the gmpy2 library formula to 1,000,000,000 decimal places
[DEBUG] 2022-10-03 15:46:46,575 compute: MainProcess    const_pi() function from the gmpy2 library calulation Done! 1 iterations and 4391.85 seconds.
[INFO] 2022-10-03 15:46:46,575 <module>: MainProcess Last 5 digits of π were 45519 as expected at offset 999,999,995
[INFO] 2022-10-03 15:46:46,575 <module>: MainProcess Calculated π to 1,000,000,000 digits using a formula of:
 11     const_pi() function from the gmpy2 library 
[INFO] 2022-10-03 15:46:46,575 <module>: MainProcess Calculation took 1 iterations and 1:13:11.845652.

MPmath Builtin 几乎同样快。慢约 12%(6 分钟):

python pi-pourri.py -v -a 12 -d 1,000,000,000  
[INFO] 2022-10-04 09:10:37,085 <module>: MainProcess Computing π to 1,000,000,000 digits.
[DEBUG] 2022-10-04 09:10:37,085 compute: MainProcess Starting   mp.pi() function from the mpmath library formula to 1,000,000,000 decimal places
[DEBUG] 2022-10-04 10:01:25,321 compute: MainProcess    mp.pi() function from the mpmath library calulation Done! 1 iterations and 3048.22 seconds.
[INFO] 2022-10-04 10:01:25,338 <module>: MainProcess Last 5 digits of π were 45519 as expected at offset 999,999,995
[INFO] 2022-10-04 10:01:25,340 <module>: MainProcess Calculated π to 1,000,000,000 digits using a formula of:
 12     mp.pi() function from the mpmath library 
[INFO] 2022-10-04 10:01:25,343 <module>: MainProcess Calculation took 1 iterations and 0:50:48.250337.