Java溢出问题

时间:2012-11-09 12:19:27

标签: 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

并且使用print语句:

15588, -2147468161, true

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

4 个答案:

答案 0 :(得分:6)

根据定义,

j <= Integer.MAX_VALUE总是如此。在这两种情况下,你的循环永远不会结束。

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

修改

使用Netbeans / Oracle JDK 7u9测试代码时,循环永远不会按预期结束。然而,有些人报告说他们看到了问题中描述的相同行为。 @auselen指向this similar post,指的是一个错误。

答案 1 :(得分:3)

最终条件为true是正常的,因为在最后一次迭代后,j将从Integer.MAX_VALUE转到Integer.MIN_VALUE,因此会小于i }。

但是,我不知道为什么放一个print语句会影响变量的值......据我所知,它不应该有任何副作用。

答案 2 :(得分:0)

j<=i时,循环结束,因此最后(j <= i)为真。如果您希望它为假,则必须在for循环中设置j <= i + 1

答案 3 :(得分:0)

我的结果与你没有相同。

如果没有print语句,我会得到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值中一直迭代,然后在时间内返回Integer.MAX_VALUE

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

在这种情况下,计数显示j溢出Integer.MAX_VALUE 两次,此时它显然被认为大于Integer.MAX_VALUE

这是JVM中的错误吗?


如果print语句有条件阻止40亿个printlns:

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

输出更改为:

101 2147483647
230627, -2147253122, true

第一行是在第一次溢出之前预期的,但第二行对我来说是一个谜。