【问题标题】:Calculate PI (OverflowException)计算 PI (OverflowException)
【发布时间】:2018-03-16 13:22:32
【问题描述】:

我写了一个使用无穷级数计算 PI(π)的方法:

public static decimal NilakanthaGetPI(ulong n)//Nilakantha Series
{
    decimal sum = 0;
    decimal temp = 0;
    decimal a = 2, b = 3, c = 4;
    for (ulong i = 0; i < n; i++)
    {
        temp = 4 / (a * b * c);
        sum += i % 2 == 0 ? temp : -temp;
        a += 2; b += 2; c += 2;
    }
    return 3 + sum;
}

该方法运行良好,直到迭代次数达到几十亿,这给了我一个 OverflowException,这是合乎逻辑的,因为 temp 的值大于 decimal 类型可以容纳的值。我想到了使用BigInteger,但我不能进行除法temp = 4 / (a * b * c)。使用这种方法,我可以计算PI 的前25 位十进制数字(decimal type 可以存储28 或29 位十进制数字)。有没有办法修改这个方法,使它可以计算更多的 PI 位数?

【问题讨论】:

  • 您可以使用this 公式。它可能会很慢,但您不需要存储每个数字。
  • @FCin 我真的不需要计算 PI,我只是好奇如何修改这个方法,以便它可以计算更多位数的 PI。

标签: c# loops iterator


【解决方案1】:

当然,这是您可以使用的技术。

BigInteger sumNumer = 3;
BigInteger sumDenom = 1;
BigInteger a = 2, b = 3, c = 4;
for (BigInteger i = 0; i < n; i++)
{
    BigInteger tempNumer = i % 2 == 0 ? 4 : -4;
    BigInteger tempDenom = (a * b * c);
    sumNumer = sumNumer * tempDenom + sumDenom * tempNumer;
    sumDenom = sumDenom * tempDenom;
    // TODO: reduce sum to a simpler fraction 
    a += 2; 
    b += 2; 
    c += 2;
}

当您完成循环后,您将获得一个非常接近 pi 的分数的分子和分母。现在的问题是将其转换为十进制数字,只需实现标准的小学长除法算法即可轻松完成。

将分数简化为最简单的形式并实现长除法留作练习。尝试一下!它塑造性格。

【讨论】:

    【解决方案2】:

    您可以使用任意精度的浮点库。不幸的是,我没有找到很多仍在维护的内容,但 this 可能会对您有所帮助。

    使用 APF 库,您可以以更高的数字分辨率计算结果,但会以速度和内存为代价。但是以你的例子来说,应该没问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-26
      相关资源
      最近更新 更多