问题
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