0

可能重复:
计算任意大数的阶乘,显示所有数字

这个问题可能会在这里被问一千次。我正在通过修改重复我的问题。我想计算一个大数的阶乘(max range of the number=10^6)。通常我们使用一个for循环 from i=1toi=number并且每次将旧值乘以新值。这对小数字很好,但如果我有大数字怎么办?for现在增加了循环的范围。Java 原始数据类型intlong无法处理生成的大量数据。他们只是溢出。虽然我知道BigInteger类,它可以处理这么大的输出,但for循环仍然不适合我。有人可以建议我打勾,任何计算数字阶乘的技巧吗?以下是适用于小数字的简单程序-

public long getFactorial(long number) {
    long factorial = 1;
    for (long i = 1; i <= number; ++i) {
        factorial *= i;
    }
    return factorial;
}
4

4 回答 4

10

了解该值在 10 5565708的范围内。它本身将占用大约 2 兆字节的空间。

也就是说,Guava BigIntegerMath.factorial(int)足以处理它,更重要的是,它实际上已经针对大型阶乘进行了优化——它会比简单的循环做得好得多。for(披露:我为 Guava 做出了贡献……并写了很多BigIntegerMath.factorial自己的东西。)

也就是说,我不会完全称它为快——我的基准测试表明该范围内的阶乘平均为 414 毫秒——但不会有一个真正快速的解决方案,除非没有极其重型的 bignum 库,而且我不希望那些会明显更快。

那就是如果您需要确切的值。如果你能满足于对数,那么是的,要么使用 ApachelogGamma(n+1)得到ln(n!),要么自己近似:

double logFactorial = 0;
for (int i = 2; i <= n; i++) {
  logFactorial += Math.log(i);
}

一些舍入误差可能会累积,但无论如何它应该是一个近似值。

于 2012-04-13T20:57:06.003 回答
2

对于如此大的 n 值,您可以使用称为斯特林公式的近似函数。

您可以在此处参考我的答案以获取更多详细信息: https ://softwareengineering.stackexchange.com/questions/134968/number-of-combinations/134972#134972

于 2012-04-13T20:52:50.270 回答
1

使用伽玛函数。伽玛(i + 1) = i!

org.apache.commons.math.special为 Java 提供了它。

人们通常做的是计算 log(Gamma(i+1)) 然后在对数空间中工作(乘法变成加法等)。

以下是一些其他快速计算阶乘的方法:http ://www.luschny.de/math/factorial/FastFactorialFunctions.htm

于 2012-04-13T20:55:56.393 回答
0

你使用BigIntegerfor factorial,你仍然只需要一个longfori循环变量。 i只需要达到1000000。有什么问题?

于 2012-04-13T20:53:03.980 回答