【发布时间】:2015-07-23 05:03:17
【问题描述】:
我正在为一个涉及除以非常大的数字的组合问题编写一个蛮力解决方案。我求助于 BigInteger 和 BigDecimal 来处理这些问题,但是当阶乘变得足够大以至于我无法确定时,我遇到了一个错误。
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));
这里是factorial 方法:
public static BigInteger factorial(int n) {
BigInteger result = BigInteger.ONE;
while (n != 0) {
result = result.multiply(new BigInteger(n + ""));
n--;
}
return result;
}
所有其他情况,从 n = k = num = 1 到 19,都按预期工作:打印值介于 0 和 1 之间。
一旦我达到 num = 20,sum 超过 1,sum - 1 变为负数,这让我认为这里存在溢出问题。但这可以与 BigIntegers/BigDecimals 一起使用吗?
这里可能是什么问题?在此先感谢您的帮助。
【问题讨论】:
-
你能告诉我们
factorial方法吗? -
是的,刚刚添加。谢谢@ajb
-
旁注:
BigInteger.valueOf(n)会将int或long转换为BigInteger。您无需先转换为String,这会更慢 - 由于您处于三重循环中,因此额外的时间可能会增加。
标签: java biginteger bigdecimal integer-overflow