明日テストがあり、本の説明が理解できません。助けてくれてありがとう。
public class TestClass{
public static void main(String[] args) throws Exception{
int a = Integer.MIN_VALUE;
int b = -a;
System.out.println( a+ " "+b);
}
}
出力:-2147483648 -2147483648
なぜこれは、正と負ではなく、同じ大きさの2つの負の数を出力するのですか?
サイレント整数オーバーフローのため:Integer.MIN_VALUE
は-2^31
であり、Integer.MAX_VALUE
は2^31-1
であるため、-Integer.MIN_VALUE
は2^31
、つまりInteger.MAX_VALUE + 1
です。 、これは定義上、整数には大きすぎます。したがって、オーバーフローしてInteger.MIN_VALUE
..になります。
次のことも確認できます。
System.out.println(Integer.MAX_VALUE + 1);
同じものを印刷します。
より技術的には、結果は Java言語仕様#15.18.2 によって定義されます。
整数の加算がオーバーフローした場合、結果は、十分に大きい2の補数形式で表される数学的合計の下位ビットになります。オーバーフローが発生した場合、結果の符号は2つのオペランド値の数学的合計の符号と同じではありません。
基本的に、_Integer.MAX_VALUE
_は実際には2147483647しかないため、_-Integer.MIN_VALUE
_(+ 2147483648)は、実際には整数の内部バイナリ表現の容量をオーバーフローします。したがって、結果は_Integer.MIN_VALUE
_または-2147483648に「ループバック」します。
代わりにlong b = -((long)a);
を実行すると、期待どおりの結果が得られます。
これをさらに明確に示すには:
<br>
Integer.MIN_VALUE is -2^31 = -2147483648<br>
Integer.MAX_VALUE is 2^31-1 = 2147483647
/*notice this is 1 less than the negative value above*/
<br>
1Integer.MAX_VALUE
取ることができません2147483648
。これは、整数に対して正確に1だけ大きすぎる数値です。これにより、数値が最大値から最小値であるpoingの開始までスケールに戻ります。