私はコンピュータアーキテクチャの教科書でこれに出くわしました:
厳密に負の整数を別の厳密に負の整数 (2 の補数) から減算しても、オーバーフローすることはありません。
教科書は、この主張を説明し続けていません。それは私の好奇心を刺激しました。
この記述が正しいのはなぜですか。
私はコンピュータアーキテクチャの教科書でこれに出くわしました:
厳密に負の整数を別の厳密に負の整数 (2 の補数) から減算しても、オーバーフローすることはありません。
教科書は、この主張を説明し続けていません。それは私の好奇心を刺激しました。
この記述が正しいのはなぜですか。
32 ビット整数の場合は次のようになります。他のビット長でも同じように機能します。
最大の負の数は -1 です。
最小の負の数は -2^31 です。
結果が 2^31 以上、または -2^31 より小さい場合、オーバーフローが発生します。
最大の数値から最小の数値を引くと、最大の減算結果が得られます。-1 - (-2^31) = 2^31 - 1. これは十分小さいです。
最小の数値から最大の数値を引くと、減算の最小の結果が得られます。-2^31 - (-1) = -(2^31 - 1)。これは -2^31 より大きいです。
このような減算によって取得できる数値の範囲は [MIN_INT+1,MAX_INT] であるため、オーバーフローすることはありません。
なぜ?
そのようにしましょうMIN_INT <= x,y < 0
:MIN_INT = MIN_INT-0 < x-y < 0-MIN_INT = MAX_INT+1
したがってMIN_INT < x-y < MAX_INT + 1
、「強い」<
はオーバーフローを防ぐことに注意してください。
負の符号付き整数の範囲は-1
~-(MAX_INT+1)
であるため、このような 2 つの数値の差の範囲は-MAX_INT
~MAX_INT
です。この範囲は簡単に表現できるため (完全な符号付き整数の範囲は-(MAX_INT+1)
からであることを思い出してMAX_INT
ください)、明らかにオーバーフローはあり得ません。