【问题标题】:I am getting an exception Exception in thread "main" java.lang.ArithmeticException: / by zero [duplicate]我在线程“main”java.lang.ArithmeticException:/零[重复]
【发布时间】:2017-08-17 16:11:40
【问题描述】:
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);
        }
    }
}

【问题讨论】:

  • 5277 的教员对于一个 int 来说太大了。
  • @TobiasGeiselmann 那么我应该在我的代码中更改什么。只需将 int 更改为 long?
  • 不,long 也不够大。你可以使用BigInteger

标签: java exception


【解决方案1】:

5277! 是一个 17354 位数字。

您应该意识到fact(N) / fact(N-2)N * (N-1) 相同,而不是计算fact(N) / (fact(N-2) * fact(2)),因此如果您改为计算,您的计算不会溢出。

或者,将fact() 更改为使用BigInteger 进行计算,但您实际上是在浪费时间将 5277 个数字相乘,然后再将 5275 个数字相乘,然后再除以得到一个可以通过乘以 2 个数字来计算的结果.

【讨论】:

  • 如果我不得不这样,我能做些什么改变?
  • @AashishKalia 已经告诉过你:将fact() 更改为使用BigInteger 进行计算。
【解决方案2】:

一个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

【讨论】:

  • 你能告诉我我必须在我的代码中做些什么改变,因为我真的不知道实现
  • 阅读BigInteger类,先找例子,自己尝试,如果不完全理解再回来(提出具体问题)
【解决方案3】:

您的计算大大超出了整数范围(这就是其他答案已经说过的)。溢出本身是静默发生的,只是给出错误的结果(将所有二进制数字剪切到尾随 32 位前面)。

导致java.lang.ArithmeticException: / by zero 的原因是您的(fact(N-2)*fact(2)) 的二进制表示(N=5277)有超过 32 个尾随零(实际上,它必须大约有 4000 个尾随零)。并剪辑到尾随的 32 位,即为零。这就是除以零的地方。

【讨论】:

  • 5277! 有 17354 个十进制数字,后面有 1317 个零。它有 57648 个二进制数字(位),后面有 5270 个零。
猜你喜欢
  • 2011-10-26
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多