开发者

Sieve of Erathostenes ArrayIndexOutOfBounds

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;
        }
    开发者_如何学JAVA    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);

    }

}


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜