import java.util.Scanner;
public class MathsHacker {
public static int fact(int n)
{
if(n==0)
return 1;
else
return n*fact(n-1);
}
/*
I checked for 1 test case giving an input=5277
it results in exception :
Exception in thread "main" java.lang.ArithmeticException: / by zero
*/
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int T =in.nextInt();
for(int a0 = 0; a0 < T; a0++)
{
int N = in.nextInt();
if(N==1)
{
System.out.println("0");
}
else
{
int res=fact(N)/(fact(N-2)*fact(2));
System.out.println(res);
}
}
}
答案 0 :(得分:2)
5277!
是一个17354位数字。
您应该意识到fact(N) / (fact(N-2) * fact(2))
与fact(N) / fact(N-2)
相同,而不是计算N * (N-1)
,所以如果您计算它,那么您的计算就不会溢出。
或者,更改fact()
以使用BigInteger
进行计算,但是您实际上是在浪费时间乘以5277个数字,然后乘以5275个数字并将它们除以得到可以计算的结果乘以2个数字。
答案 1 :(得分:1)
int可以容纳的最大数量是:
2 ^ 31 - 1 = 2,147,483,647
然而:
12! = 479,001,600
13! = 6,227,020,800
然后,这意味着12点之后!您无法在int
中保留该值。
虽然编译器给出的错误并不是真正明确的,但它是溢出
您可以使用long
,但仍然是:
2 ^ 63 - 1 = 9.223372036854776e18 ~ 9,223,372,036,854,776,000
21! = 5.109094217170944e19 ~ 51,090,942,171,709,440,000
你可以看到它仍然溢出......
因此,更好的建议是使用BigInteger
类
答案 2 :(得分:0)
你的计算大量溢出整数范围(这就是其他答案已经说过的)。溢出本身就是静默发生的,只是给出错误的结果(在尾随的32位前面剪掉所有二进制数字)。
导致java.lang.ArithmeticException: / by zero
的原因是你的(fact(N-2)*fact(2))
的N = 5277的二进制表示具有超过32个尾随零(实际上,它必须是大约4000个尾随零)。并剪切到尾随的32位,即零。这就是除零的地方。