我在线程“main”java.lang.ArithmeticException中获得异常异常:/由零

时间:2017-08-17 16:11:41

标签: java exception

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);
        }
    }
}

3 个答案:

答案 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位,即零。这就是除零的地方。