我一直在使用Java的这个因子程序:
public static long factorial(int a) {
if(a<1) {
return 1;
}
long result=1;
long x=a;
while(x>1) {
result*=x;
x--;
}
return result;
}
然而,似乎“破坏”并在25的阶乘后返回一个负数。它返回一个负数,然后只返回“0”。
我做错了导致这种情况吗?
答案 0 :(得分:7)
你已经溢出long
请改用BigInteger
。
答案 1 :(得分:4)
25! = 15511210043330985984000000
Java中long的最大值为2^63-1 = 9223372036854775807
(source)。
25!大约是1.7 * 10 ^ 6的长度可以存储在Java中的最大值。请改用BigInteger
。
答案 2 :(得分:3)
25!大于Long.MAX_VALUE
...
答案 3 :(得分:1)
根据JLS,溢出(和下溢)是静默的,这就是为什么你的结果是&#34;惊喜&#34;。
您有两种选择:
double
(尽管即使这会溢出170!
)答案 4 :(得分:0)
另一种不那么天真且适用于非整数的方法是使用伽玛函数的自然对数。
http://www.iro.umontreal.ca/~simardr/ssj/doc/html/umontreal/iro/lecuyer/util/Num.html
如果您必须坚持使用此实现,我建议您查看memoization。为什么要重新计算价值?一旦你有了一个,请挂上它,然后重复请求。
答案 5 :(得分:0)
查看http://en.wikipedia.org/wiki/Integer_overflow,我知道标题是指整数,但原则代表int,long,double等。
简而言之,原始数据类型具有最大值,当您重新执行该操作时,它会包含aroun并重新启动。如果你真的想要了解它,请学习二进制加法以完全理解它。
答案 6 :(得分:0)
这就是你所缺少的:当有符号整数基元类型(例如short,int,long)增加到它可以表示的有符号值之上时,它会尝试翻转它的符号位,这是最左边的位,它只能用于表示数字的符号。符号位中的1表示负值。这种现象称为整数溢出。
考虑一个虚构的3位有符号原始数据类型(为了比较,Java long是64位)。它可以表示-4到3之间的数字。
3,3位数可以表示的最大正值,如下所示:011
将1添加到011,得到:100(数字部分溢出到符号部分)
100的十进制版本是-4
但是,当你处理long的容量时,需要计算很多位数,所以这里有一个快速的方法来确定给定的非递减序列(在这种情况下,factorial)定义的最大数字:
long n = 1;
while (factorial(n) > 0) {
System.out.println("factorial of " + n++ + " can fit in a long!");
}
这看起来应该是一个无限循环,但事实并非如此;最终,factorial(n)将因整数溢出而返回负值。 这将为您提供以下输出:
factorial of 1 can fit in a long!
factorial of 2 can fit in a long!
factorial of 3 can fit in a long!
factorial of 4 can fit in a long!
factorial of 5 can fit in a long!
factorial of 6 can fit in a long!
factorial of 7 can fit in a long!
factorial of 8 can fit in a long!
factorial of 9 can fit in a long!
factorial of 10 can fit in a long!
factorial of 11 can fit in a long!
factorial of 12 can fit in a long!
factorial of 13 can fit in a long!
factorial of 14 can fit in a long!
factorial of 15 can fit in a long!
factorial of 16 can fit in a long!
factorial of 17 can fit in a long!
factorial of 18 can fit in a long!
factorial of 19 can fit in a long!
factorial of 20 can fit in a long!