Java 函数返回NaN
我创建了一个程序来计算这个算法,从k=1开始,到k=100结束: 以下是我创建的代码:Java 函数返回NaN,java,algorithm,nan,factorial,exponent,Java,Algorithm,Nan,Factorial,Exponent,我创建了一个程序来计算这个算法,从k=1开始,到k=100结束: 以下是我创建的代码: public static void calculatePi() { BigInteger firstFactorial; BigInteger secondFactorial; BigInteger firstMultiplication; BigInteger firstExponent; BigInteger secondExponent; int fi
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;
}
publicstaticvoidcalculatepi(){
大整数阶乘;
大整数二阶阶乘;
大整数乘法;
大整数指数;
大整数二次指数;
int firstNumber=1103;
大整数加法;
双总和pi=3.0;
双电流PI=3.0;
双pi=3.0;
int secondNumber=2;
双第三个数字=数学sqrt(2.0);
第四个整数=9801;
双前缀=1;
对于(int i=1;i问题:
这些行可能是发生错误的地方:
summationPi = firstFactorial.intValue()*firstAddition.intValue();
summationPi /= firstExponent.intValue()*secondExponent.intValue();
原因是您正在对biginger
调用intValue()
,该函数不能保证返回完整的值(因为int
只能保存32位数据。这也可能与将结果存储为double
而不是bigdecimic
)有关
然后取该可能的NaN
值,并将其用作除法中的除数
解决方案:
请注意,我可以通过将多行合并为一行来消除summationPi
。此外,在divide()
方法中出现的MathContext
设置为10000
,这可以更改为您想要的任何精度
有关BigDecimal
,.的详细信息,此问题的原因如下:
summationPi/=firstExponent.intValue()*secondExponent.intValue()
如果secondExponent的值随着i的增大而变大,如果使用intValue()方法检索其int值,则会得到0。NaN通常是由0除以0引起的(请参见此处的其他可能原因:)。您应该在调试器中单步执行代码,或添加大量打印语句,以便分离出导致NaN的第一个计算。@DanW:我怀疑这就是OP要演示的内容(请参见函数名)…@DanW我知道,这只是一个占位符:)@Toby它更像是一个笑话。如果只返回3.1415926535897932384626433832795028841;
,或者定义一个常量,不是效率会更高吗?这样做会给我带来很多错误,因为Firadition、firstExponent和secondExponent不是大小数,而是大整数。每当运行t时,我都会得到这个结果线程“main”java.lang.arithmetricException中的代码(第53行是您的代码)异常:非终止十进制扩展;没有精确表示的十进制结果。在picalculator.picalculator.main(picalculator.java:24)的java.math.BigDecimal.divide(BigDecimal.java:1603)处Java结果:1@Toby这是MathContext
的一个函数。我会再次更新它。很抱歉。我仍然会收到相同的错误,线程“main”java.lang中出现异常。算术异常:非终止十进制扩展;没有精确的可表示十进制结果。在java.math.BigDecimal.divide(BigDecimal.java:1603)在picalculator.picalculator.calculator.calculatePi(picalculator.java:60)在picalculator.picalculator.main(picalculator.java:25)上,java结果:1我认为这行是:prefix=prefix/fourthNumber
。您还需要将BigDecimal
和MathContext
的相同概念应用于前缀
。
BigDecimal currentPi = BigDecimal.ONE;
currentPi = currentPi.add(
new BigDecimal(firstFactorial.multiply(firstAddition))
.divide(new BigDecimal(firstExponent.multiply(secondExponent)), new MathContext(10000)));