【问题标题】:How to solve Exception in thread “main” java.lang.ArithmeticException: / by zero?如何解决线程“主”java.lang.ArithmeticException:/中的异常为零?
【发布时间】:2014-10-20 09:54:50
【问题描述】:

这里是代码:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;

public class prob_c {

    public static void main(String args[]) throws IOException {
        Scanner x = null;
        try {
            x = new Scanner(new File("prob_c.in"));
        } catch (FileNotFoundException ex) {
            System.out.print("File not found!");
        }
        for (int a = 0; a < 10; a++) {
            int counter = 0;
            int n = x.nextInt();
            int r = x.nextInt();
            counter++;
            long res = 1;
            res = getFact(n) / (getFact(n - r) * getFact(r));
            System.out.println(res);
        }
    }

    public static long getFact(int j) {
        long f = 1;
        for (int i = j; i >= 1; i--) {
            f *= i;
        }
        return f;
    }
}

【问题讨论】:

  • 就像编写一个检查零的 if 条件一样简单。你没有办法阻止它。
  • 这不是一个坏问题。我相信明显被零除实际上是由计算阶乘时的整数溢出引起的。不是通过实际尝试除以零。遗憾的是,每个人都宁愿投反对票或近距离投票也不愿发布有关整数溢出的有用答案并使用BigInteger 而不是long
  • 你能写出触发异常的输入吗? (prob_c.in 的内容)
  • 5 3 5 2 5 5 4 2 10 7 20 9 52 5 100 0 75 30 1 1 28 18 每行两个数字

标签: java exception combinations


【解决方案1】:

要处理大阶乘,您需要使用BigInteger 类而不是long 来存储数字。

如果您将n 中的所有数字乘以n - r + 1 然后除以getFact(r),也可以更有效地计算getFact(n) / (getFact(n - r) * getFact(r)),或者将n 中的所有数字乘以@ 987654328@,然后除以getFact(n - r)

您得到除以零错误的原因是阶乘的二进制扩展往往以很多零结束。例如,如果你用二进制写20!,它会以 18 个零结尾(如果我计算正确的话)。在计算阶乘时,每次乘以另一个偶数,最后都会得到更多的零。

现在,如果您取一个以 64 个或更多零结尾的数字,并尝试将其放入 long,那么除了最后 64 位之外的所有内容都将被截断 - 这是整数溢出。这意味着如果n - rr 足够大,getFact(n - r) * getFact(r) 可以被截断为零。这就是您除以零误差的来源。

【讨论】:

    猜你喜欢
    • 2012-06-04
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    • 2015-02-10
    相关资源
    最近更新 更多