计算PI(OverflowException)

时间:2018-03-16 13:22:32

标签: c# loops iterator

我写了一个通过使用无穷级数来计算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数字?

2 个答案:

答案 0 :(得分:0)

您可以使用任意精度浮点库。不幸的是,我没有找到很多仍然保留的但是this可能会帮助你。

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

答案 1 :(得分:0)

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

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的分数的分子和分母。现在的问题是将其转换为十进制数字,只需通过实施标准的小学长除法算法就可以轻松完成。

将分数缩减到最简单的形式并实现长分割是一项练习。试试吧!它构建了角色。