Java 查找较大素数时出错

Java 查找较大素数时出错,java,primes,sieve,Java,Primes,Sieve,我制作了一个简单的erastothenes筛选程序来计算euler项目的素数之和。它适用于100、1000、10000等等,但当我使用100万或200万时,它会给我以下信息: java.lang.ArrayIndexOutOfBoundsException: -2146737495 这不会发生在较小的数字上,我使用布尔数组 boolean[] primes = new boolean[2000001]; ArrayList<Integer> list = new ArrayL

我制作了一个简单的erastothenes筛选程序来计算euler项目的素数之和。它适用于100、1000、10000等等,但当我使用100万或200万时,它会给我以下信息:

java.lang.ArrayIndexOutOfBoundsException: -2146737495

这不会发生在较小的数字上,我使用布尔数组

boolean[] primes = new boolean[2000001];
    ArrayList<Integer> list = new ArrayList<Integer>();
    for (int i = 2; i < primes.length; i++){
        primes[i] = true;
    }
    boolean stop = false;
    int target = 2;
    int cycles = 1;
    while (!stop) {
        list.add(target);
        for (int i = target;; i ++) //
        {
            if (target*i >= primes.length ) {//
                break;
            }
            primes[target*i] = false;//

        }
        for (int i = target + 1; ; i ++) {

            if(i >= primes.length) {
                stop = true;
                break;
            }
             else if (primes[i]) {
                target = i;
                break;
            }
        }
        cycles ++;
    }
    int sum = 0;
        for (int i = 0; i < list.size(); i++) {
        sum += list.get(i);;
    }
boolean[]primes=new boolean[2000001];
ArrayList=新建ArrayList();
for(int i=2;i=素数长度){//
打破
}
素数[target*i]=false//
}
for(inti=target+1;;i++){
如果(i>=素数长度){
停止=真;
打破
}
else if(素数[i]){
目标=i;
打破
}
}
循环++;
}
整数和=0;
对于(int i=0;i

我的目标并不是真正地找到答案,但很多时候,由于这些类型的错误,我已经放弃了我的代码。我想为它们找到一个源。

这是因为您使用的是int,其上限为2^31-1:请参阅


要处理大数字,您应该使用类。

这是因为您使用的是int,其上限为2^31-1:请参阅


要处理大的数字,您应该使用类。

您的
素数
数组有问题

首先,通过读取错误,您的数组显然不够长,无法容纳逻辑,因为您将其定义为
boolean[]primes=new boolean[200001]并且您的ArrayIndexOutOfBoundsException为-2146737495


因此,对于变量
i
target
cycles
,尝试使用长整数或大整数而不是整数。即使如此,您也必须重新考虑您的逻辑,因为问题不是溢出本身,而是不够长的数组。

您的
primes
数组有问题

首先,通过读取错误,您的数组显然不够长,无法容纳逻辑,因为您将其定义为
boolean[]primes=new boolean[200001]并且您的ArrayIndexOutOfBoundsException为-2146737495


因此,对于变量
i
target
cycles
,尝试使用长整数或大整数而不是整数。即使如此,您也必须重新考虑您的逻辑,因为问题不是溢出本身,而是不够长的数组。

您的错误检查没有考虑整数溢出

for (int i = target;; i ++) //
{
    if (target*i >= primes.length ) {// This is the check
        break;
    }
    primes[target*i] = false;// Here is where it overflows

}
一旦你点击了一个使
target*i
大于整数所能容纳的
i
,整数就会溢出。这意味着现在它将变成负值。当然,对于负数,
target*i>=primes.length
将为false

当然,负数不能是数组中的索引。它应该在休息时停止,但没有停止,因为不符合条件

您应该做的是计算允许的最大
i
,并将其作为循环条件:

int maxI = primes.length / target;
for (int i = target; i < maxI; i ++) //
{
    primes[target*i] = false;// Here is where it overflows
}

如果您有一个巨大的
目标

您有一个不考虑整数溢出的错误检查,则有必要在
if
中进行检查,以避免溢出

for (int i = target;; i ++) //
{
    if (target*i >= primes.length ) {// This is the check
        break;
    }
    primes[target*i] = false;// Here is where it overflows

}
一旦你点击了一个使
target*i
大于整数所能容纳的
i
,整数就会溢出。这意味着现在它将变成负值。当然,对于负数,
target*i>=primes.length
将为false

当然,负数不能是数组中的索引。它应该在休息时停止,但没有停止,因为不符合条件

您应该做的是计算允许的最大
i
,并将其作为循环条件:

int maxI = primes.length / target;
for (int i = target; i < maxI; i ++) //
{
    primes[target*i] = false;// Here is where it overflows
}

如果有一个巨大的
目标

整数溢出,则有必要检查
if
,以避免溢出。我怀疑
target*I
溢出。它在哪一行崩溃?你试过调试你的代码吗?还要注意的是,(inti=target;;i++){if(target*i>=primes.length){break;}…}
可以替换为(inti=target;target*i
46349*46349=2148229801,支持的最大值
int
是2147483647,换行并变为负数。整数溢出。我怀疑
target*I
溢出。它在哪一行崩溃?你试过调试你的代码吗?还要注意的是,(inti=target;;i++){if(target*i>=primes.length){break;}…}
可以替换为(inti=target;target*i46349*46349=2148229801,支持的最大值
int
是2147483647,换行并变为负数。请注意,这样您将无法使用数组,因为数组的索引始终是整数。请注意,这样您将无法使用数组,因为数组的索引始终是整数。数组足够长。用于确保不超出数组的检查是错误的。逻辑是错误的IMHO,因此我认为解决方案不是检查索引是否超出数组,而是更改如何查找较大的素数。数组足够长。用来确保不超出数组的检查是错误的。逻辑是错误的IMHO,因此我认为解决方案不是检查索引是否超出数组,而是改变如何找到更大的素数。