オーバーフローについて読んだことがありますが、「オーバーフローとは、数値が大きすぎてデータ型に収まらない場合であるため、システムは次に小さい値に「ラップアラウンド」し、そこからカウントアップします」。
例えば:
short s = (short)1921222; // Stored as 20678
その例では、 -32768(Short.MIN_VALUE)
しかし、別の整数データ型で証明しようとすると、同じように機能しないようです...
byte b = (byte)400; // Stored as -112
上記の例はからカウントを開始しました それが私が見つけた唯一の方法でした -112
何か間違ったことをしているのかわかりません。
Java言語仕様 は次のように述べています。
整数型は、値がそれぞれ8ビット、16ビット、32ビット、64ビットの符号付き2の補数整数であるbyte、short、int、およびlongと、値が16ビットの符号なし整数であるcharです。 UTF-16コードユニットを表します。
したがって、short
とbyte
は両方とも 2の補数 整数です。
short
は16ビットです。つまり、2 ^ 16 = 65536の異なる値を保持できます。 65536番目の値の後、オーバーフローします。
1921222モジュロ65536は20678です。これは32768(2 ^ 15、2の補数のターニングポイント)未満であるため、正の数を維持します。
byte
は8ビットです。つまり、2 ^ 8 = 256の異なる値を保持できます。これは256番目の値の後にオーバーフローします。 256を法とする400は144です。この値は、2の補数のターニングポイントである128よりも大きいため、負の2の補数として解釈されます。
Javaでは、byte
プリミティブ型は8 bit
signed整数であるため、呼び出しから-112
を取得しました。 :
byte b = (byte) 400;
次のように0xFF
をバイナリで追加することで、これを回避して符号なしの値を取得できます。
int b = (byte) 400 & 0xFF;
詳細については、以下を確認できます。
他の答えに加えて、手動計算によってもその答えを得ることができます。
Javaでは、データ型byte
は8ビットの符号付き整数です。したがって、値は[-128, 127]
の間隔にあります。 400
の値があり、そのタイプの実際の値を確認したい場合は、間隔内の値に達するまで、その数値から間隔のsizeを引くことができます。 。
先ほど言ったように、byte
は8ビットなので、間隔のサイズは256
です。初期値からそれを引きます:400 - 256 = 144
。この値はまだ間隔の外にあるため、もう一度減算する必要があります:144 - 256 = -112
。この値は現在、間隔内にあり、実際にテストで確認した値です。
最初の例でも同じことが言えます。short
は16ビットで符号付きなので、間隔は[-32768, 32767]
、サイズは65536
です。値1921222
から繰り返し減算を行うと、テストで見られるように、最終的に値20678
が得られます。