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

そしてprintステートメントは:

15588, -2147468161, true

どちらの場合も、最終条件はを返す必要falseがありますが、を返しますtrue。誰でもこれを説明できますか。

4

4 に答える 4

6

j <= Integer.MAX_VALUE定義上、常に真です。どちらの場合も、ループは終了しません。

これをに変更するj < iと、ループが終了し、printステートメントに関係なく同じ回答が返されます。

編集

Netbeans / Oracle JDK 7u9を使用してコードをテストする場合、ループが期待どおりに終了することはありません。ただし、質問で説明されているのと同じ動作が見られるという報告もあります。@auselenは、バグを参照しているこの同様の投稿を指しています。

于 2012-11-09T12:25:20.257 に答える
3

最終的な条件はtrue、最後の反復後にjがからInteger.MAX_VALUEになりInteger.MIN_VALUE、したがって、よりも小さくなるためiです。

ただし、printステートメントを配置すると変数の値に影響する理由はわかりません...私が知る限り、副作用はないはずです。

于 2012-11-09T12:24:31.667 に答える
0

ループは、j<=toiのときに終了します。したがって、最後に(j <= i)trueになります。falseにしたい場合j <= i + 1は、forループで設定する必要があります。

于 2012-11-09T12:25:28.483 に答える
0

私はあなたとまったく同じ結果を得ることができません。

printステートメントがないと、とが得られInteger.MAX_VALUE - 1ますtrue

ループは実際に時間を実行し4294967395ます(これを確認するには、に変更countlongてください)。

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 2回Integer.MAX_VALUEあることを示しており、その時点で明らかに!?より大きいと見なされます。

これはJVMのバグですか?


印刷ステートメントに40億回の印刷を防止する条件がある場合:

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

出力は次のように変わります。

101 2147483647
230627, -2147253122, true

最初の行は最初のオーバーフローの前から予想されますが、2番目のカウントは私には謎です。

于 2012-11-09T12:55:19.887 に答える