考虑计算一个数的阶乘的问题。 当结果大于2 ^ 32时,我们将得到溢出错误。 我们如何设计一个程序来计算大数的阶乘?
编辑:假设我们使用的是C ++语言。
EDIT2:这是this one
的重复问题答案 0 :(得分:2)
仅作为标记算法的问题。您的2 ^ 32不是问题,因为算法永远不会出现溢出错误。算法的实现可以并且确实存在溢出错误。那你用的语言是什么?
大多数语言都有可以使用的BigNumber或BigInteger。
这是一个C ++ BigInteger库:https://mattmccutchen.net/bigint/
我建议你谷歌:c++ biginteger
答案 1 :(得分:1)
如果您可以使用近似值,请考虑使用Stirling approximation并以双精度计算它。
如果你想要精确的值,你需要arbitrary-precision arithmetic和大量的计算时间......
答案 2 :(得分:1)
这样做需要你采取一些方法,但基本归结为:
这样,数组中的每个int /元素都有一个位置大小,最后可以串起来组成你的整数。
C中的一个很好的例子:http://www.go4expert.com/forums/c-program-calculate-factorial-t25352/
答案 3 :(得分:1)
测试此脚本:
import gmpy as gm
print gm.fac(3000)
对于非常大的数字很难存储或打印结果。
答案 4 :(得分:1)
出于某些目的,例如计算组合的数量,计算阶乘的对数就足够了,因为你将使用阶乘法对因子进行除法,最终结果的大小更合理 - 你只需减去对数在取结果的指数之前。
您可以通过添加对数或使用http://en.wikipedia.org/wiki/Gamma_function来计算阶乘的对数,{{3}}通常在数学库中可用(有很好的方法来估算它)。
答案 5 :(得分:0)
首先发明一种存储和使用大数字的方法。常见的方法是将整数数组解释为大数字的数字。然后向系统添加基本操作,例如乘法。然后乘以。
或使用已经制作的解决方案。 Google for:c ++大整数库
答案 6 :(得分:0)
您可以使用BigInteger查找可能大于65的Big阶乘数,因为数据类型的长范围为65!然后它开始返回0。请参考下面的Java代码。希望对您有所帮助:
import java.math.BigInteger;
public class factorial {
public factorial() {
// TODO Auto-generated constructor stub
}
public static void main(String args[])
{
factorial f = new factorial();
System.out.println(f.fact(100));
}
public BigInteger fact(int num)
{
BigInteger sum = BigInteger.valueOf(1);
for(int i = num ; i>= 2; i --)
{
sum = sum.multiply(BigInteger.valueOf(i));
}
return sum;
}
}
答案 7 :(得分:0)
如果要扩大测量范围,可以使用对数。对数会将您的乘法转换为加法,从而使其存储起来小得多。
factorial(n) => n * factorial(n-1)
log(factorial(n)) => log(n) * log(factorial(n-1))
5! = 5*4*3*2*1 = 120
log(5!) = log(5) + log(4) + log(3) + log(2) + log(1) = 2.0791812460476247
In this example, I used base 10 logarithms, but any base works.
10^2.0791812460476247
Or 10^0.0791812460476247*10^2 or 1.2*10^2