3

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

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。任何人都可以解释这一点。

4

4 回答 4

6

j <= Integer.MAX_VALUE根据定义总是正确的。在这两种情况下,您的循环都不会结束。

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

编辑

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

于 2012-11-09T12:25:20.257 回答
3

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

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

于 2012-11-09T12:24:31.667 回答
0

我得到的结果和你不太一样。

没有 print 语句,我得到Integer.MAX_VALUE - 1and true

循环实际执行4294967395次数(更改count为 along以查看此内容):

long count = 0; // make this change

输出是:

4294967395, 2147483646, true

4294967395确切地说,这意味着它会一直Integer.MAX_VALUE - Integer.MIN_VALUE + 100迭代每个int值,然后再次返回Integer.MAX_VALUE

从理论上讲,循环永远不应该终止,因为 an 不可能int超过Integer.MAX_VALUE,但它确实会终止。

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

这是JVM中的错误吗?


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

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

输出变为:

101 2147483647
230627, -2147253122, true

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

于 2012-11-09T12:55:19.887 回答
0

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

于 2012-11-09T12:25:28.483 回答