Sieve of Erathostenes ArrayIndexOutOfBounds

眉间皱痕 提交于 2020-01-15 09:42:28

问题


trying to implement a simple sieve of erathosthenes to solve this question on project euler :

The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.

Find the sum of all the primes below two million.

Link

My code keeps returning this error however :

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2147479015 at Prime.main(Prime.java:28)

Can anyone give me any hints as to why? Here is the code:

import java.math.BigInteger;

public class Prime {
    /*
     * Input: an integer n > 1
     * 
     * Let A be an array of bool values, indexed by integers 2 to n, initially
     * all set to true.
     * 
     * for i = 2, 3, 4, ..., while i^2 ≤ n: if A[i] is true: for j = i^2, i^2 +
     * i, i^2 + 2i, ..., while j ≤ n: A[j] = false
     * 
     * Now all i such that A[i] is true are prime.
     */

        import java.math.BigInteger;

public class Prime {
    /*
     * Input: an integer n > 1
     * 
     * Let A be an array of bool values, indexed by integers 2 to n, initially
     * all set to true.
     * 
     * for i = 2, 3, 4, ..., while i^2 ≤ n: if A[i] is true: for j = i^2, i^2 +
     * i, i^2 + 2i, ..., while j ≤ n: A[j] = false
     * 
     * Now all i such that A[i] is true are prime.
     */

    public static void main(String[] args) {
        boolean[] array = new boolean[2000000];
        BigInteger counter = new BigInteger("0");
        for (int value = 0; value < array.length; value++) {
            array[value] = true;
        }
        for (int i = 2; i < array.length; i++) {
            if (array[i]) {
                int j = i * i;
                while (j > 0 && j < array.length) {
                    array[j] = false;
                    j += i;
                }
            }
        }
        for (int i = 2; i < array.length; i++) {
            if (array[i]) {
                counter = counter.add(BigInteger.valueOf(i));
            }
        }
        for (int value = 2; value < array.length; value++) {
            if(array[value]){
                System.out.println(value + ", ");
            }
        }
        System.out.println("\n" + counter);

    }

}

回答1:


The problem is coming from these lines:

        int j = i * i;
        while (j <= array.length) {
            array[j] = false;
            j += i;
        }

What's happening is that sometimes i * i is so big that it rounds the corner (overflows) and becomes negative. Java does not have 'checked' integer math. To fix this, you'll want to change your while condition to the following

while(j > 0 && j < array.length)

Also, your array is of size 200,000 and not 2,000,000.




回答2:


Not to be snarky, but it's because you're going out of the bounds of the array. Your limit for i is the length of the array, and then j is equalling at a minimum the square of i. j is then being used as the location of the array to be accessed at line 28, which is out of bounds.



来源:https://stackoverflow.com/questions/7707354/sieve-of-erathostenes-arrayindexoutofbounds

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!