StackOverflowError计算BigInteger的阶乘?
我正在尝试编写一个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
。 有没有其他方法来处理它?
这里的问题看起来像是来自过多递归的堆栈溢出 (5000个递归调用看起来像是关于吹出Java 调用堆栈的正确调用次数)而不是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; }
希望这可以帮助!
问题不是BigInteger,而是你使用递归方法调用( getFactorial()
)。
试试这个,一个迭代算法:
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; }
来自Google的Guava库具有高度优化的factorial实现,可输出BigIntegers。 看看吧 。 (它可以实现更平衡的乘法,并优化简单的移位。)
在实际情况下,对于阶乘的朴素实现并不奏效。
如果您有严重的需求,最好的办法是编写一个伽玛函数(或ln(gamma)
函数),它不仅可以用于整数,还可以用于十进制数。 记住结果,这样您就不必使用WeakHashMap
继续重复计算WeakHashMap
而且您正在开展业务。