使用基本算术以任意精度计算 Pi

发布于 2024-10-08 05:09:35 字数 508 浏览 9 评论 0原文

我正在寻找一个公式/算法来计算给定精度的 PI~3.14。

公式/算法必须只有非常基本的算术,如

  • +: 加法
  • -: 减法
  • *: 乘法
  • /: 除法,

因为我想在 C++ 中实现这些运算,并希望实现尽可能简单(不允许使用 bignum 库)。

我发现这个计算 Pi 的公式非常简单:(

Pi/4 = 1 - 1/3 + 1/5 - 1/7 + ...  = sum( (-1)^(k+1)/(2*k-1) , k=1..inf )

注意 (-1)^(k+1) 可以通过上述运算符轻松实现)。

但这个公式的问题是无法指定要计算的位数。换句话说,没有直接的方法来确定何时停止计算。

也许解决此问题的方法是计算第 n-1 项和第 n 项计算项之间的差异,并将其视为当前误差。

不管怎样,我正在寻找一个具有这些属性并且能够更快地收敛到 Pi 的公式/算法

I am looking for a formula/algorithm to calculate PI~3.14 in a given precision.

The formula/algorithm must have only very basic arithmetic as

  • +: Addition
  • -: Subtraction
  • *: Multiplication
  • /: Divison

because I want to implement these operations in C++ and want to keep the implementation as simple as possible (no bignum library is allowed).

I have found that this formula for calculating Pi is pretty simple:

Pi/4 = 1 - 1/3 + 1/5 - 1/7 + ...  = sum( (-1)^(k+1)/(2*k-1) , k=1..inf )

(note that (-1)^(k+1) can be implemented easily by above operators).

But the problem about this formula is the inability to specify the number of digits to calculate. In other words, there is no direct way to determine when to stop the calculation.

Maybe a workaround to this problem is calculating the difference between n-1th and nth calculated term and considering it as the current error.

Anyway, I am looking for a formula/algorithm that have these properties and also converges faster to Pi

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

探春 2024-10-15 05:09:35

键盘链接

#include <iostream>
#include <cmath>
int main()
{
    double p16 = 1, pi = 0, precision = 10;

    for(int k=0; k<=precision; k++)
    {
        pi += 1.0/p16 * (4.0/(8*k + 1) - 2.0/(8*k + 4) - 1.0/(8*k + 5) - 1.0/(8*k+6));
        p16 *= 16;
    }
    std::cout<<std::setprecision(80)<<pi<<'\n'<<M_PI;
}

输出:

3.141592653589793115997963468544185161590576171875
3.141592653589793115997963468544185161590576171875

这实际上是Bailey-Borwein-Plouffe 公式,也取自维基百科的链接。

Codepad link:

#include <iostream>
#include <cmath>
int main()
{
    double p16 = 1, pi = 0, precision = 10;

    for(int k=0; k<=precision; k++)
    {
        pi += 1.0/p16 * (4.0/(8*k + 1) - 2.0/(8*k + 4) - 1.0/(8*k + 5) - 1.0/(8*k+6));
        p16 *= 16;
    }
    std::cout<<std::setprecision(80)<<pi<<'\n'<<M_PI;
}

Output:

3.141592653589793115997963468544185161590576171875
3.141592653589793115997963468544185161590576171875

This is actually the Bailey-Borwein-Plouffe formula, also taken from the link from wikipedia.

美男兮 2024-10-15 05:09:35

在您的原始(缓慢收敛)示例中,可以计算误差项,因为这是一个交替序列;请参阅 http://en.wikipedia.org/wiki/Alternating_series#Approximating_Sums

本质上,下一个未计算的项是误差的界限。

In your original (slowly converging) example, the error term can be computed because this is an alternating series; see http://en.wikipedia.org/wiki/Alternating_series#Approximating_Sums

Essentially, the next uncomputed term is a bound on the error.

飘然心甜 2024-10-15 05:09:35

您只需执行 arctan(1) 的泰勒包络,然后将所有其余部分相加即可得到 pi/4。
arctan(1) 的泰勒包络

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

您也可以使用 z=1 的欧拉公式,然后将结果乘以 4。

http://upload.wikimedia.org/math/2/7/9/279bed5a2ea3b80a71f5b22078090168.png

You can just do the Taylor envelope of the arctan(1) and then you will get pi/4 just summing all the rest part.
The taylor envelope of arctan(1)

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

also you can use the euler formula with z=1 and then multiply the result by 4.

http://upload.wikimedia.org/math/2/7/9/279bed5a2ea3b80a71f5b22078090168.png

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文