我创建了一个程序,计算从k = 1开始并以k = 100结束的算法:
这是我创建的代码:
public static void calculatePi() {
BigInteger firstFactorial;
BigInteger secondFactorial;
BigInteger firstMultiplication;
BigInteger firstExponent;
BigInteger secondExponent;
int firstNumber = 1103;
BigInteger firstAddition;
double summationPi = 3.0;
double currentPi = 3.0;
double pi = 3.0;
int secondNumber = 2;
double thirdNumber = Math.sqrt(2.0);
int fourthNumber = 9801;
double prefix = 1;
for(int i=1;i<101;i++){
firstFactorial = factorial(4*i);
secondFactorial = factorial(i);
firstMultiplication = BigInteger.valueOf(26390*i);
firstExponent = exponent(secondFactorial, 4);
secondExponent = exponent(BigInteger.valueOf(396),4*i);
firstAddition = BigInteger.valueOf(firstNumber).add(firstMultiplication);
summationPi = firstFactorial.intValue()*firstAddition.intValue();
summationPi /= firstExponent.intValue()*secondExponent.intValue();
currentPi += summationPi;
}
prefix = secondNumber*thirdNumber;
prefix = prefix/fourthNumber;
summationPi = summationPi*prefix;
pi = 1/summationPi;
System.out.println("Pi is: " + pi);
return;
}
函数指数(a,b);返回^ b的结果。函数factorial(a)返回a的阶乘。我已经证明这两个功能都能很好地工作。然而,代码似乎神秘地回归“NaN”。我明白当事情被零除以时就会发生这种情况,但是我无法找到任何将零除以零的点。还有什么会导致这个/我做错了吗?
注意:在for语句中,我在算法中使用i作为k。
提前致谢!
答案 0 :(得分:2)
这些行很可能发生错误:
summationPi = firstFactorial.intValue()*firstAddition.intValue();
summationPi /= firstExponent.intValue()*secondExponent.intValue();
原因是您在intValue()
上调用了BigInteger
,但无法保证返回完整值(因为int
只能保存32位数据。这可能也可以将结果存储为double
而不是BigDecimal
)。
然后取出可能的NaN
值并将其用作分部中的除数。
BigDecimal currentPi = BigDecimal.ONE;
currentPi = currentPi.add(
new BigDecimal(firstFactorial.multiply(firstAddition))
.divide(new BigDecimal(firstExponent.multiply(secondExponent)), new MathContext(10000)));
请注意,我可以通过将多行合并为一行来消除summationPi
。此外,MathContext
方法中出现的divide()
设置为10000
,可以将其更改为您想要的任何精度。
有关BigDecimal
,check the API。
答案 1 :(得分:0)
此问题的原因在于此行:
summationPi / = firstExponent.intValue()* secondExponent.intValue();
其中secondExponent的值变得如此之大,以至于如果使用intValue()方法检索其int值,则会得到0。