StackOverflowError计算BigInteger的阶乘?

时间:2012-01-24 18:57:56

标签: java algorithm stack-overflow biginteger factorial

我正在尝试编写一个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>

5 个答案:

答案 0 :(得分:28)

这里的问题看起来像是来自stack overflowrecursion(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继续重复计算,而且您正在开展业务。