解决“可能的精度损失”后的 ArrayIndexOutOfBounds编译错误

发布于 2024-12-11 18:12:51 字数 1282 浏览 0 评论 0原文

有效:意味着没有精度错误::只是数组越界

long a[] =new long[1000000];
int no=2,n;
long i;
a[no]=i+a[n];
if(a[no]>longChain)
{
    longChain = a[no];
    startNo = no;
}

,当我这样做时

long a[] =new long[1000000];
long no=2,n;
long i,longChain=1,startNo;
a[no]=i+a[n];
if(a[no]>longChain)
{
    longChain = a[no];
    startNo = no;
}

精度损失

,发现

:需要长:int

问题是什么?

我针对上述问题的代码,其 ProjectEuler 问题编号 14

class P14
{
    public static void main(String args[])
    {
        long a[] =new long[1000000];
        long no=2,n;
        long i,longChain=1,startNo;
        a[1]=1;
        while(no<1000000)
        {
            n=no;
            i=0;
            while(n>no-1)
            {
                if(n%2==0)
                    n=n/2;
                else
                    n=3*n+1;
                i++;
                //System.out.println(n);
            }
            a[no]=i+a[n];
            if (a[no] > longChain)
            {
                longChain=a[no];
                startNo=no;
            }
            no++;
            //System.out.println(no);
        }
    }
}

这是我针对上述问题发生位置的代码

答案:: 将 a[no] 替换为 a[(int)n]

a[n],a[(int)n]

works:meaning no precision error::Just array out of bounds

long a[] =new long[1000000];
int no=2,n;
long i;
a[no]=i+a[n];
if(a[no]>longChain)
{
    longChain = a[no];
    startNo = no;
}

and when I do

long a[] =new long[1000000];
long no=2,n;
long i,longChain=1,startNo;
a[no]=i+a[n];
if(a[no]>longChain)
{
    longChain = a[no];
    startNo = no;
}

then loss of precision

found:long

required: int

what is the problem?

My Code for above problem, its ProjectEuler Problem No. 14

class P14
{
    public static void main(String args[])
    {
        long a[] =new long[1000000];
        long no=2,n;
        long i,longChain=1,startNo;
        a[1]=1;
        while(no<1000000)
        {
            n=no;
            i=0;
            while(n>no-1)
            {
                if(n%2==0)
                    n=n/2;
                else
                    n=3*n+1;
                i++;
                //System.out.println(n);
            }
            a[no]=i+a[n];
            if (a[no] > longChain)
            {
                longChain=a[no];
                startNo=no;
            }
            no++;
            //System.out.println(no);
        }
    }
}

This is my code for where above problem is occurring

Answer:: Replace a[no] by a[(int)n]

a[n],a[(int)n]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

魔法少女 2024-12-18 18:12:51

你的 no 和 n 变量需要是 int,而不是 long。数组不能按 long 进行索引。将代码更改为:

int no=2,n;

使代码编译。

ArrayIndexOutOfBoundsException 是因为您编写的算法假设它是长整型。

这段代码最终会导致 n 变为负数:

n=3*n+1;

当您进行整数算术时,很难明白为什么。稍作更改即可使代码使用长算术并打印中间结果,从而准确显示何时变为负值以及如何变为负值:

while(n>no-1)
{
    long newN = n;

    if (n % 2 == 0) newN = newN / 2L;
    else newN = 3L * newN + 1L;

    if (newN > Integer.MAX_VALUE) System.out.println("about to fail");

    //this is where the magic happens
    n = (int)newN;
    System.out.println("converted " + newN + " to " + n);

    i++;
}

your no and n variables need to be int, not long. Arrays can't be indexed by long. Changing the code to:

int no=2,n;

makes the code compile.

The ArrayIndexOutOfBoundsException is because you wrote the algorithm assuming it was longs.

This code will eventually cause n to become negative:

n=3*n+1;

It's hard to see why when you're doing integer arithmetic. A slight change to make the code use long arithmetic and print the interim result reveals exactly when it becomes negative and how:

while(n>no-1)
{
    long newN = n;

    if (n % 2 == 0) newN = newN / 2L;
    else newN = 3L * newN + 1L;

    if (newN > Integer.MAX_VALUE) System.out.println("about to fail");

    //this is where the magic happens
    n = (int)newN;
    System.out.println("converted " + newN + " to " + n);

    i++;
}
谢绝鈎搭 2024-12-18 18:12:51

这可能是因为数组索引采用 int 作为索引。但所有变量的类型都是long

a[no]

no 是一个long

因此,使用 long 作为数组索引是隐式向下转型,可能会导致精度损失。

因此,要么手动将其强制转换,要么将 no 更改为 int

编辑:(在问题中添加附加信息后)

我不确定这是否是原因:

n=3*n+1;

您在index.html中使用n。但 n 一开始可能会变得相当大。因此 *3 可以使其大于数组的大小。

您可能应该仔细检查您的算法是什么。 (我无法从代码本身弄清楚)

This is likely because array indexing takes an int as the index. But all your variables are of type long.

a[no]

no is a long.

So using long as an array index is an implicit downcast which could result in loss of precision.

So either you manually cast it down, or you change no to an int.

EDIT: (after additional info in the question)

I'm not 100% sure if this is the cause:

n=3*n+1;

You use n as in index. But n can get pretty large to begin with. So a *3 could make it larger than the size of the array.

You should probably double-check whatever your algorithm is. (which I can't figure out from the code itself)

征棹 2024-12-18 18:12:51

您遇到的问题是您无法将正在计算的所有可能值存储在数组中。数字可以增长到超过 2^31-1 并且出现溢出。

你可以做的是 make

long n;

and

while (n > no - 1 || n >= a.length) {

}
// is safe as n < a.length;
a[no] = i + a[(int) n];

这确保你只查找数组内的缓存值。

The problem you have is that you cannot store all the possible values you are calculating in array. Numbers can grow beyond 2^31-1 and you get an overflow.

What you can do is make

long n;

and

while (n > no - 1 || n >= a.length) {

}
// is safe as n < a.length;
a[no] = i + a[(int) n];

This ensures you only look up cached values which are inside your array.

红玫瑰 2024-12-18 18:12:51

n 需要很长,因为对于 int 来说它可能太大。 (如果您使用 int,它将溢出为负数并导致 ArrayIndexOutOfBoundsException。)

您必须将 n 声明为 long 并在将其用作索引时将其强制转换为 int (< code>no 可以是 int)

a[no]=i+a[(int)n];

n needs to be long because it may get too large for int. (If you use int it will overflow into negative numbers and cause the ArrayIndexOutOfBoundsException.)

You have to declare n as long and cast it to int when using it as index (no can be int)

a[no]=i+a[(int)n];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文