[英]BitSet(JAVA) is throwing outofBoundsException in the implementation of Sieve Of Eratosthenes
這是我實現Eratosthenes篩網的功能,
void solve() throws IOException {
int n = 200000;
ArrayList<Integer> primes = new ArrayList<Integer>();
BitSet bs = new BitSet(n + 1);
for(int i = 0; i <= n + 1; i++)
bs.set(i);
//setting bits at 0 and 1 to 0, since these are not considered as primes
bs.clear(0);
bs.clear(1);
for(int i = 2; i <= n + 1; i++) {
if(bs.get(i)) {
//cross out multiples of i starting from i*i (lesser one would have always been crossed out)
for(int j = i*i; j <= n + 1; j += i)
{
bs.clear(j);
}
primes.add(i); //add this prime to the list
}
}
for(int e : primes)
out.println(e);
}
當我運行這個時,我在內部for循環中得到了arrayOutOfBoundsException,即
for(int j = i*i; j <= n + 1; j += i)
{
bs.clear(j); //EXCEPTION is raised here
}
我收到的錯誤消息是:
Exception in thread "main" java.lang.IndexOutOfBoundsException: bitIndex < 0: -2146737495
at java.util.BitSet.clear(BitSet.java:532)
at ERATOSTHENES.solve(ERATOSTHENES.java:45)
我不明白問題出在哪里,如果我將n減少到20000,則我的代碼可以正常工作,但是在n = 168000(大約)之后,它顯示此OutofBoundsException。
它是BitSet特有的東西,我沒有得到的某些屬性嗎?
您將在此行中出現整數溢出( i*i
為負):
for(int j = i*i; j <= n + 1; j += i)
例:
System.out.println(168000 * 168000);
打印:
-1840771072
這是負數,因此小於n + 1
並通過了循環條件。
您正在初始化(在最壞的情況下)變量i
為接近200,000的大數(特別是大質數?)。 這意味着j
,其被初始化為i * i
,將在過量的400億,這是顯著超過的最大值int
(約21.47億),這意味着它們會溢出到負值,這肯定會超出范圍。
為了解決這種情況下的問題,請將變量聲明為long
類型long
該類型為64位並且可以容納更大的值。
我認為可能是因為您使用的是int且數字變得太大,即
200,000 * 200,000是一個巨大的數字,可能應該更長。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.