Java抛出除零错误?

时间:2017-11-09 15:15:23

标签: java math

为了重新学习如何用Java编写代码,我一直在经历Project Euler的一些问题。我写的以下代码是解决问题3:找到数字600851475143的最大素数因子。

public class ProjectEuler {
/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    // TODO code application logic here
    ProjectEuler t = new ProjectEuler();
    System.out.println(t.findLargestPrime(600851475143L));

}

public Boolean isPrime(int x) {
    Boolean answer = true;
    for (int i = 2; i < x/2; i++) {
        if (x%i == 0) {
            answer = false;
    }

}
    return answer;
}

public int findLargestPrime(Long max) {
    int largest = 1;
    for (int i = 2 ; i < max/2; i++) {
        if (max%i == 0 && isPrime(i) && i > largest) {
            largest = i;
        }
    }
    return largest;
}

}

然而,当我运行它时,代码抛出算术错误,因为我试图除以零?这里显示了实际的错误消息:

Exception in thread "main" java.lang.ArithmeticException: / by zero
at projecteuler.ProjectEuler.findLargestPrime(ProjectEuler.java:37)
at projecteuler.ProjectEuler.main(ProjectEuler.java:19)

我不知道我是否在某个地方犯了一个愚蠢的错误,或者这是一个我不明白的Java怪癖?任何人都可以对此有所了解吗?

谢谢。

2 个答案:

答案 0 :(得分:7)

for (int i = 2 ; i < max/2; i++)最终会溢出(因为600851475143 / 2大于Integer.MAX_VALUE),最终i将等于0 max%i i将抛出该异常。

如果您想阻止它发生,请将long更改为int(您还应将所有其他long更改为 <Grid VerticalAlignment="top" Margin="0,40,0,0" Background="White"> <ContentPresenter /> </Grid> )。< / p>

答案 1 :(得分:0)

这不是实际问题的答案,但是:您不必检查最多max的所有数字,甚至不需要检查除数是否为素数。您只需(反复)将max除以您找到的任何除数i

long l = 600851475143L;
for (int i = 2; i <= Math.sqrt(l); i++) {
    if (l % i == 0) {
        System.out.println(i);
        l /= i;
        i--;
    }
}
System.out.println("--> " + l);

这样,你知道这个除数必须是素数 - 如果它是复合的,max已经被它的分量除。这也意味着你不必一直循环到max(对于给定的值,这将花费很长时间),但只能达到最大的素数除数,这可能是多少小。一旦达到sqrt(l) - 当前值为l,而不是原始版本! - 你可以停止,因为不会有任何高于此的除数,l的剩余值将是最终的(因此也是最大的)素数因子。

因此,这将复杂性从大约O(n²)降低到大约O(n 1/2 )。

相关问题