私はJavaの初心者であり、これとかなり混乱しています。
System.out.println(4*2147483647)
Javaで-4に等しいのはどうですか?
これは、整数のサイレントオーバーフローが原因です。
2147483647 == Integer.MAX_VALUE
整数の最大値です。
サイレントオーバーフローとは、2147483647 + 1 == Integer.MIN_VALUE = -2147483648
それを確認できることを意味します2147483647 + 2147483647 == 2147483647 + (-2147483648 + - 1) == -2
言い換えれば、、、2147483647 * 2 == -2
そしてあなたは今理由を見ることができます2147483647 * 4 == -4
。
より技術的には、結果はJava言語仕様#15.17.1によって定義されています。
整数の乗算がオーバーフローした場合、結果は、十分に大きい2の補数形式で表される数学積の下位ビットになります。その結果、オーバーフローが発生した場合、結果の符号は2つのオペランド値の数学積の符号と同じではない可能性があります。
これは、プロセッサがバイナリマルチプリケーションを実行する方法と関係があります。そこにある数は最大符号付き整数であり、0111111111111111111111111として表されます(ここでは数を確認していませんが、理解できたと思います)。
4を掛け算すると、2を左にシフトするようなものになり、結果は11111111111111111111100(-4を表します)になります。バイナリで多重化がどのように行われるかを読みたいと思うかもしれません。
結果がの範囲外であるためint
。
プリミティブデータ型
これを解決するには、のlong
代わりにを使用しint
ます。
問題は、int(4バイト)を使用していて、long(8バイト)を使用していないことです。
System.out.println(4*2147483647);
結果が整数ではなく長くなるように、数値の1つの後にl(レマの場合)を追加してみてください。整数の最大値が結果よりも小さい http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Integer.html#MAX_VALUE
System.out.println(4l * 2147483647);
また
System.out.println(4 * 2147483647l);
上記の2つは正しい結果をもたらします。それは8589934588です
コンピュータシステムのほとんどの整数は32ビットに基づいています。これは4バイトを意味します(64ビット以上も使用できます)。32ビット整数で最大4,294,967,295を使用できます。したがって、4,294,967,295 + 5はオーバーフローを引き起こし、5を与えます。また、-1は整数で4,294,967,295を意味します。負のビットがあるからです。
詳細: http: //en.wikipedia.org/wiki/Integer_overflow
これは、コンピュータが数値をメモリに保存する方法が原因です。2147483647 * 4 = 8589934588
8589934588のバイナリ結果は111111111 1111 1111 1111 1111 1111 1100
最初のものは、それが先行する数が負であることを意味するビットです。
次の部分は2の補数で説明できます。
2の補数は、すべてのビットを反転してから1つを加算することによって計算される、負の値を表す方法です。これにより、0011(最後の4バイトの反転)が発生し、1を追加すると、4のバイナリ表現である0100になります。
符号ビットが負であるため、結果は-4になります。