簡體   English   中英

BitSet(JAVA)在實現Eratosthenes篩選時拋出outofBoundsException

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM