我已经编写了下面的Java代码来递归地计算从1到30的数字因子。由于某些原因,对于大于20的数字,输出与results here不匹配。我也很惊讶地看到负数。
代码
class Test {
public static Long factorial(Long number) {
if(number == 1){
return 1L;
}else{
return number*factorial(number-1);
}
}
public static void main(final String... arguments){
for(Long number=1L;number<=30;number++){
System.out.println("Factorial of " + number + " : " + factorial(number));
}
}
}
输出
Factorial of 1 : 1
Factorial of 2 : 2
Factorial of 3 : 6
Factorial of 4 : 24
Factorial of 5 : 120
Factorial of 6 : 720
Factorial of 7 : 5040
Factorial of 8 : 40320
Factorial of 9 : 362880
Factorial of 10 : 3628800
Factorial of 11 : 39916800
Factorial of 12 : 479001600
Factorial of 13 : 6227020800
Factorial of 14 : 87178291200
Factorial of 15 : 1307674368000
Factorial of 16 : 20922789888000
Factorial of 17 : 355687428096000
Factorial of 18 : 6402373705728000
Factorial of 19 : 121645100408832000
Factorial of 20 : 2432902008176640000
Factorial of 21 : -4249290049419214848
Factorial of 22 : -1250660718674968576
Factorial of 23 : 8128291617894825984
Factorial of 24 : -7835185981329244160
Factorial of 25 : 7034535277573963776
Factorial of 26 : -1569523520172457984
Factorial of 27 : -5483646897237262336
Factorial of 28 : -5968160532966932480
Factorial of 29 : -7055958792655077376
Factorial of 30 : -8764578968847253504
有人可以帮我正确计算最多30的阶乘吗?
答案 0 :(得分:4)
它不起作用,因为你超过了long可以表示的最大数量。它的最小值为-9,223,372,036,854,775,808,最大值为9,223,372,036,854,775,807(含)。负数出现是因为当你超过最大值时,java会滚动到底片中。找到一种表示数字的不同方式。
答案 1 :(得分:4)
这就是&#34;溢出&#34;。 Longs以64位存储;它们的最大值是2 ^ 63 - 1,即9,223,372,036,854,775,807。而是尝试使用BigInteger。使用BigInteger有点棘手,因为实例化和操作与普通的int / long不同。以下是为BigInteger重新编写的代码:
public class BigIntFactorial {
public static BigInteger factorial(BigInteger number) {
if(number.equals(BigInteger.ONE)) {
return BigInteger.valueOf(1);
} else {
return number.multiply(factorial(number.subtract(BigInteger.ONE)));
}
}
public static void main(final String... arguments){
for(Long number=1L;number<=30;number++){
System.out.println("Factorial of " + number + " : " + factorial(BigInteger.valueOf(number)));
}
}
}
输出是:
Factorial of 1 : 1
Factorial of 2 : 2
Factorial of 3 : 6
Factorial of 4 : 24
Factorial of 5 : 120
Factorial of 6 : 720
Factorial of 7 : 5040
Factorial of 8 : 40320
Factorial of 9 : 362880
Factorial of 10 : 3628800
Factorial of 11 : 39916800
Factorial of 12 : 479001600
Factorial of 13 : 6227020800
Factorial of 14 : 87178291200
Factorial of 15 : 1307674368000
Factorial of 16 : 20922789888000
Factorial of 17 : 355687428096000
Factorial of 18 : 6402373705728000
Factorial of 19 : 121645100408832000
Factorial of 20 : 2432902008176640000
Factorial of 21 : 51090942171709440000
Factorial of 22 : 1124000727777607680000
Factorial of 23 : 25852016738884976640000
Factorial of 24 : 620448401733239439360000
Factorial of 25 : 15511210043330985984000000
Factorial of 26 : 403291461126605635584000000
Factorial of 27 : 10888869450418352160768000000
Factorial of 28 : 304888344611713860501504000000
Factorial of 29 : 8841761993739701954543616000000
Factorial of 30 : 265252859812191058636308480000000
答案 2 :(得分:1)
你似乎遇到了这样一个问题,即阶乘的速度非常快。大于可以用长的数字表示的最大数字。而在java中,这意味着价值&#34;翻身&#34;并变得消极。
一种解决方案是使用BigInteger。它具有可变的位数,因此您可以在其中表示几乎任何大小的数字,并且您不会遇到溢出问题。请注意,当我说几乎,我的意思是在某些实现中,biginteger仅限于Integer.MAX_VALUE位,并且你不应该遇到这个限制。
另一种解决方案是用双打来表示数字。他们有更高的限制而不是多头,但代价是失去一些精确度。我没有运行这些数字,但你应该可以计算30!
当你真的想要超越限制时,你可以做的另一个很酷的事情是使用fft来计算非常高精度数的乘法。更多信息请访问:http://numbers.computation.free.fr/Constants/Algorithms/fft.html
编辑:运行数字,双精度很好