如何解决线程“main”中的异常java.lang.ArithmeticException:/由零?

时间:2014-10-20 09:54:50

标签: java exception combinations

这是代码:

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

1 个答案:

答案 0 :(得分:1)

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

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

你得到零除错误的原因是因子的二进制扩展往往以很多零结束。例如,如果您以二进制形式编写20!,则以18个零结束(如果我已正确计数)。当你计算出一个阶乘,每当你乘以另一个偶数时,你会得到更多的零。

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