Java溢出问题



我编写了以下代码,在我有打印语句时,它以不同的答案。

class test
{
    public static void main(String args[])
    {
      int i = Integer.MAX_VALUE;
      int j = Integer.MAX_VALUE-100;
      int count = 0;
      for(; j<=i; j++){
        count++;
        //System.out.println(j); // If we remove comment, answer is different
      }
     System.out.println(count + ", " + j + ", " + (j<=i));        
    }
}

没有打印语句的答案是:

101, -2147483648, true

使用打印语句是:

15588, -2147468161, true

在两种情况下,最终条件都应返回false,但返回true。任何人都可以解释一下。

j <= Integer.MAX_VALUE始终是正确的。在这两种情况下,您的循环永远不会结束。

如果将其更改为 j < i,则循环将终止,无论打印语句如何,都将返回相同的答案。

编辑

使用NetBeans/Oracle JDK 7U9测试代码时,循环永远不会按预期结束。但是,有些人报告说,他们看到了与问题中描述的相同行为。@auselen指向这一类似的帖子,该帖子指的是错误。

最终条件是true是正常的,因为在最终迭代后,j将从Integer.MAX_VALUE转到CC_7,因此变得小于i

但是,我不知道为什么放置打印说明会影响变量的值...据我所知,它不应该有任何副作用。

j<=i时,循环完成,因此,最后,(j <= i)是正确的。如果您希望它是错误的,则必须在for循环中设置j <= i + 1

我没有得到与您相同的结果。

没有打印语句,我得到Integer.MAX_VALUE - 1true

循环实际执行4294967395次(将count更改为long以查看此信息):

long count = 0; // make this change

输出是:

4294967395, 2147483646, true

4294967395恰好是 Integer.MAX_VALUE - Integer.MIN_VALUE + 100,这意味着它始终遍历每个int值,然后返回到a second time的 Integer.MAX_VALUE

从理论上讲,循环永远不会终止,因为int不可能超过Integer.MAX_VALUE,但是 dos 终止。

在这种情况下,计数表明j溢出Integer.MAX_VALUE 两次,这显然被认为大于Integer.MAX_VALUE!?

这是JVM中的错误?


如果打印语句有预防40亿个printlns的条件:

if (j > Integer.MAX_VALUE - 1)
     System.out.println(count + " " + j);

输出对此发生了变化:

101 2147483647
230627, -2147253122, true

第一行是从第一个溢出之前开始的,但第二行对我来说是一个谜。

最新更新