Java 当除以阶乘时,BigDecimal除法失效
我正在写一个组合数学问题的蛮力解决方案,这个问题涉及到除以非常大的数。我转向BigInteger和BigDecimal来处理这些,但当阶乘变得足够大以至于我无法确定时,我遇到了一个错误Java 当除以阶乘时,BigDecimal除法失效,java,biginteger,bigdecimal,integer-overflow,Java,Biginteger,Bigdecimal,Integer Overflow,我正在写一个组合数学问题的蛮力解决方案,这个问题涉及到除以非常大的数。我转向BigInteger和BigDecimal来处理这些,但当阶乘变得足够大以至于我无法确定时,我遇到了一个错误 int n = num; int k = num; BigDecimal sum = new BigDecimal("0"); BigDecimal factorialN = new BigDecimal(factorial(n)); BigInteger factoria
int n = num;
int k = num;
BigDecimal sum = new BigDecimal("0");
BigDecimal factorialN = new BigDecimal(factorial(n));
BigInteger factorialI;
BigInteger factorialJ;
BigInteger factorialM;
BigInteger denominator;
double threePowerN = pow(3, n);
for (int i = 0; i < k; i++) {
for (int j = 0; j < k; j++) {
for (int m = 0; m < k; m++) {
if (i + j + m == n) {
factorialI = factorial(i);
factorialJ = factorial(j);
factorialM = factorial(m);
denominator = factorialI.multiply(factorialJ);
denominator = denominator.multiply(factorialM);
denominator = denominator.multiply(new BigInteger(String.valueOf((int)threePowerN)));
BigDecimal lastTerm = new BigDecimal(denominator);
lastTerm = factorialN.divide(lastTerm, 100, RoundingMode.HALF_EVEN);
sum = sum.add(lastTerm);
}
}
}
}
// prints
// -0.62366051209329651, which doesn't make sense because this should
// be a percentage between 0 and 1.
System.out.println(new BigDecimal("1").subtract(sum));
所有其他情况下,从n=k=num=1到19,所有工作均按预期进行:打印值介于0和1之间。
一旦我达到num=20,sum
超过1,sum-1
变为负值,这让我觉得这里有溢出问题。但这可能是大整数/大小数吗?
这里有什么问题?提前感谢你的帮助 320太大,无法装入int
。因此,这将失败:
denominator = denominator.multiply(new BigInteger(String.valueOf((int)threePowerN)));
演员阵容将环绕,你将实际乘以一个负数
biginger
具有pow
功能。而不是:
double threePowerN = pow(3, n);
试一试
然后
denominator = denominator.multiply(threePowerN);
顺便说一下,您不必将整数转换为
String
,就可以将它们转换为biginger
BigInteger
没有接受整数值的构造函数,但它有一个。你能给我们展示一下factorial
方法吗?是的,刚刚添加。谢谢@ajbSide注意:biginger。valueOf(n)
将int
或long
转换为biginger
。您不需要首先转换为字符串,这会更慢,而且由于您处于三重循环中,额外的时间可能会累积起来。谢谢您的帮助。我认为新的threePowerN应该写成biginger-threePowerN=biginger.valueOf(3).pow(n)
pow
方法作用于对象本身,它不接受第二个参数。
BigInteger threePowerN = BigInteger.valueOf(3).pow(n);
denominator = denominator.multiply(threePowerN);