4

int値の範囲に疑問があります

int x=2147483647;     /*NO Error--this number is the maximum range 
                        of int value no error*/
int y=2147483648;     /*Error--one more than the
                        maximum range of int*/
int z=2147483647+1;  /*No Error even though it is one more
                       than the maximum range value*/

なぜ ?

4

7 に答える 7

8

ここでは、Java 言語仕様に関する説明を示します。

整数リテラル ( JLS 3.10.1 ) のセクションには、次のように書かれています。

int 型の最大の 10 進数リテラルは2147483648(2 31 ) です。0からまでのすべての 10 進リテラルは2147483647、int リテラルが出現する可能性がある場所に出現する可能性がありますが、リテラル2147483648は単項否定演算子 のオペランドとしてのみ出現する可能性があります-

そう ...

  • 最初のステートメントは、正当な整数リテラル値の代入です。コンパイルエラーなし。

  • 21474836482 番目のステートメントは、前に単項否定演算子がないため、コンパイル エラーです。

  • 3 番目のステートメントには、範囲外の整数リテラルが含まれていないため、その観点からはコンパイル エラーではありません。

代わりに、3 番目のステートメントは、JLS 15.18.2で説明されている 2 項加算式です。これは、整数の場合について次のように述べています。

整数の加算がオーバーフローした場合、結果は十分に大きな 2 の補数形式で表される数学的合計の下位ビットになります。オーバーフローが発生した場合、結果の符号は、2 つのオペランド値の数学的な合計の符号と同じではありません。

したがって、2147483647 + 1オーバーフローして にラップし-2147483648ます。


@Peter Lawrey は、3 番目のステートメントが "コンパイラによって書き直される" 可能性があることを (軽率に?) 示唆しており+2147483648、その結果、コンパイル エラーが発生します。

これは正しくありません。

JLS には、定数式が非定数式とは異なる意味を持つ可能性があると述べているものは何もありません。それどころか、1 / 0JLS のような場合には、物事をひっくり返して、式が異常終了するため、式は定数式ではないと言います。( JLS 15.28にあります)

JLS は、一部の Java コンストラクトがコンパイラによって異なることを意味するケースを回避するために非常に努力しています。たとえば、変数が使用される前に常に初期化されていると賢いコンパイラだけが推測できる場合を避けるために、「明確な代入」ルールに非常にこだわっています。これは、コードの移植性の観点からは良いことです。

コンパイラの実装者がプラットフォーム固有の処理を実行できる唯一の重要な領域は、同時実行性と Java メモリ モデルの領域です。これには、実用的な合理的な理由があります。それは、マルチスレッド Java アプリケーションをマルチコア/マルチプロセッサ ハードウェア上で高速に実行できるようにするためです。

于 2011-02-28T10:13:42.697 に答える
2

intInteger.MIN_VALUE(-2147483648)からInteger.MAX_VALUE(2147483647)の範囲。

ただし、int範囲に対してチェックされるのはリテラルのみです。

Java は、指定された定数値式が範囲内に収まるかどうかをチェックしません。

計算はこれらの境界を通過することが「許可」されていますが、オーバーフローが発生します (つまり、結果の値の下位ビットのみが格納されます)。したがって、計算2147483647 + 1 計算内で明確に定義されてintおり、-2147483648 です。

于 2011-02-28T09:38:06.403 に答える
1

3 つ目は整数オーバーフローと呼ばれるからです。あなたは計算をしていて、オーバーフローしています。他のものは単なる定数です。

于 2011-02-28T09:35:07.240 に答える
1

なぜなら

int z=2147483647+1;

と等しくない、オーバーフローする2147483648

于 2011-02-28T09:36:22.230 に答える
1

最初の 2 つのケースは明らかです。3 番目のケースは静かにオーバーフローします。したがって、そのような場合は、呼び出し元のコードで常に処理する必要があります。

于 2011-02-28T09:39:19.970 に答える
0

3 番目の式は int ベースの加算であるため、結果を int の範囲内の値にキャストします。

于 2011-02-28T09:36:53.070 に答える
0

の範囲intInteger.MIN_VALUEInteger.MAX_VALUEです。Java は静かにオーバーフローするため、計算の結果はコンパイラによって検出されません。(ただし、IDE によって検出される場合があります)

最も驚くべきオーバーフロー操作の 1 つは、-Integer.MIN_VALUE

于 2011-02-28T09:36:56.323 に答える