简体   繁体   English

BitSet(JAVA)在实现Eratosthenes筛选时抛出outofBoundsException

[英]BitSet(JAVA) is throwing outofBoundsException in the implementation of Sieve Of Eratosthenes

Here is my function for 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);
}

When I run this I get and arrayOutOfBoundsException during the inner for loop, ie 当我运行这个时,我在内部for循环中得到了arrayOutOfBoundsException,即

for(int j = i*i; j <= n + 1; j += i)
{
  bs.clear(j);            //EXCEPTION is raised here
}

Error Message that I am getting is: 我收到的错误消息是:

Exception in thread "main" java.lang.IndexOutOfBoundsException: bitIndex < 0: -2146737495
at java.util.BitSet.clear(BitSet.java:532)
at ERATOSTHENES.solve(ERATOSTHENES.java:45)

I dont understand where is the problem, if I reduce n to 20000, then my code works fine, but after n = 168000 (approx.), it shows this OutofBoundsException. 我不明白问题出在哪里,如果我将n减少到20000,则我的代码可以正常工作,但是在n = 168000(大约)之后,它显示此OutofBoundsException。

Is it something specific to BitSet, some property that I am not getting? 它是BitSet特有的东西,我没有得到的某些属性吗?

You are getting an integer overflow in this line ( i*i is negative): 您将在此行中出现整数溢出( i*i为负):

for(int j = i*i; j <= n + 1; j += i)

Example: 例:

System.out.println(168000 * 168000);

Prints: 打印:

-1840771072

Which is negative, so is less than n + 1 and passes cycle condition. 这是负数,因此小于n + 1并通过了循环条件。

You are initialising (in the worst case) the variable i to be a large number close to 200,000 (specifically a large prime number?). 您正在初始化(在最坏的情况下)变量i为接近200,000的大数(特别是大质数?)。 That means j , which is initialised as i * i , will be in excess of 40,000,000,000, which is significantly over the max value of int (approx. 2,147,000,000) That means they will overflow over to negative values, which will definitely be out of range. 这意味着j ,其被初始化为i * i ,将在过量的400亿,这是显著超过的最大值int (约21.47亿),这意味着它们会溢出到负值,这肯定会超出范围。

To solve the problem in this case, declare your variables to be of type long which is 64-bit and can hold much larger values. 为了解决这种情况下的问题,请将变量声明为long类型long该类型为64位并且可以容纳更大的值。

I think it could be because you are using an int and the number is getting too big ie 我认为可能是因为您使用的是int且数字变得太大,即

200,000 * 200,000 is a huge number and should probably be a long instead. 200,000 * 200,000是一个巨大的数字,可能应该更长。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM