java.lang.ArrayIndexOutOfBoundsException:-2146737495

时间:2015-11-03 15:56:54

标签: java

我有以下方法:

public static boolean[] mk2(int n) {
    boolean[] isPrime = new boolean[n + 2];
    isPrime[1] = false;
    isPrime[2] = true;
    for (int i = 3; i <= n; i++) {
        if((i & 1) == 0) {
           isPrime[i] = false;
        } else {
           isPrime[i] = true;
        }
    }
    // cycle through to see if a number has factors other than 1 & itself
    for(int y = 3; y <= n; y++) {
        System.out.print("Test y " + y);
        if(isPrime[y]) {
            for(int i = 2; i <= y-1; i++) {
                if(y%i==0){
                    // stop here if it isn't prime
                    isPrime[y] = false;
                    System.out.println(" disproved");
                    i = y + 1;
                }     
            }
            if(isPrime[y]){
                    System.out.println(" is prime and disproves:");
                    for (int j = y; y*j <= n; j++) {
                        if(y*j<=n) {
                            isPrime[y*j] = false;
                            System.out.print(" "+(y*j)+" ");
                        }
                    }
                    System.out.println(".");
                }
        } else {
            System.out.println(" already disproved");
        }
    }
    System.out.println("Primes");
    int x = 0;
    for(int i=1; i <= n; i++) {
        if(isPrime[i]) {
            System.out.print(i+", ");
            x++;
        }
        if(x >= 61) {
            System.out.println(";");
            x = 0;
        }
    }
    System.out.println(".");

    return isPrime;
}

通常工作正常但是当我将n设置为100000时,我得到以下异常java.lang.ArrayIndexOutOfBoundsException: -2146737495

当我试图访问数组中大于其定义大小的点时,通常会发现{p> 1} {/ 1>。

java.lang.ArrayIndexOutOfBoundsException

所以我对这里发生的事情感到有些困惑。 任何想法?

4 个答案:

答案 0 :(得分:2)

错误很可能来自int的算术溢出。

最可能的根本原因是您对元素isPrime[y*j]的引用,其中y * j溢出int并返回Integer.MIN_VALUE + (the amount overflown - 1)

您应该设置断点并调试这些值。

答案 1 :(得分:1)

有问题的陈述是isPrime[y*j] = false;,它会生成Integer范围之外的数字。一旦达到最大数量并从否定数字开始,您就会得到异常,因为索引应为>= 0 and < len

更具体地说,您试图将y= 46349, j=46349乘以2148229801,其大于Integer.MAX_VALUE=2147483647

答案 2 :(得分:0)

  

当整数溢出时,它会回到最小值并且   从那里继续。如果它下溢,它会回到最大值   价值并从那里继续。

所以根据

java.lang.ArrayIndexOutOfBoundsException: -2146737495

因为索引必须是正数:

根据java语言规范:

  

在运行时检查所有数组访问;尝试使用索引   小于零或大于或等于的长度   数组导致抛出ArrayIndexOutOfBoundsException。

https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.13

答案 3 :(得分:0)

int是32位,long是64位。所以它提供了更大的范围。你应该做的是将变量j和y转换为longs:

for(long y = 3; y <= n; y++) {

for (long j = y; y*j <= n; j++) {

无论您将数组编入索引,都需要将其转换为

if(isPrime[(int)y]) {

发生的事情是你将两个超过int范围的整数相乘并因此变为负数且下面的条件满足为真:

if(y*j<=n) {

然后它试图在你的数组中分配一些负面索引:

    isPrime[y*j] = false;