我正在尝试编写一个Java程序来计算大数的阶乘。似乎BigInteger
无法容纳如此庞大的数字。
以下是我写的(简单)代码。
public static BigInteger getFactorial(BigInteger num) {
if (num.intValue() == 0) return BigInteger.valueOf(1);
if (num.intValue() == 1) return BigInteger.valueOf(1);
return num.multiply(getFactorial(num.subtract(BigInteger.valueOf(1))));
}
上述程序在5022中处理的最大数量,之后程序抛出StackOverflowError
。有没有其他方法可以处理它?</ p>
答案 0 :(得分:28)
这里的问题看起来像是来自stack overflow的recursion(5000个递归调用看起来与吹出Java call stack的正确呼叫次数相似)而不是限制BigInteger
。迭代地重写阶乘函数应该解决这个问题。例如:
public static BigInteger factorial(BigInteger n) {
BigInteger result = BigInteger.ONE;
while (!n.equals(BigInteger.ZERO)) {
result = result.multiply(n);
n = n.subtract(BigInteger.ONE);
}
return result;
}
希望这有帮助!
答案 1 :(得分:3)
问题不在于BigInteger,而是您使用递归方法调用(getFactorial()
)。
答案 2 :(得分:2)
尝试使用迭代算法:
public static BigInteger getFactorial(int num) {
BigInteger fact = BigInteger.valueOf(1);
for (int i = 1; i <= num; i++)
fact = fact.multiply(BigInteger.valueOf(i));
return fact;
}
答案 3 :(得分:0)
Google的Guava库具有高度优化的factorial实现,可输出BigIntegers。 Check it out。 (它可以实现更平衡的乘法,并优化简单的移位。)
答案 4 :(得分:0)
阶乘的朴素实现在实际情况下无法解决。
如果您有严重的需求,最好的办法是编写一个gamma函数(或ln(gamma)
函数),它不仅可以用于整数,还可以用于十进制数。记下结果,这样您就不必使用WeakHashMap
继续重复计算,而且您正在开展业务。