Java 查找较大素数时出错
我制作了一个简单的erastothenes筛选程序来计算euler项目的素数之和。它适用于100、1000、10000等等,但当我使用100万或200万时,它会给我以下信息: java.lang.ArrayIndexOutOfBoundsException: -2146737495 这不会发生在较小的数字上,我使用布尔数组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
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*iint
是2147483647,换行并变为负数。请注意,这样您将无法使用数组,因为数组的索引始终是整数。请注意,这样您将无法使用数组,因为数组的索引始终是整数。数组足够长。用于确保不超出数组的检查是错误的。逻辑是错误的IMHO,因此我认为解决方案不是检查索引是否超出数组,而是更改如何查找较大的素数。数组足够长。用来确保不超出数组的检查是错误的。逻辑是错误的IMHO,因此我认为解决方案不是检查索引是否超出数组,而是改变如何找到更大的素数。