ターゲットのデータ型で結果を表すことができない場合、オーバーフローが発生します。値 -72 は、符号付きの 8 ビット量である char で表すことができます...この例ではオーバーフローはありません。おそらく、ビット単位の減算を行っているときに a について考えていると思います... aから aborrow
を減算するときは、次の上位ビット位置からする必要があります。減算を行う場合、借用を無視することはできません。'1'
'0'
borrow
-35 decimal is 11011101 in two's complement 8-bit
+37 decimal is 00100101 in two's complement 8-bit
最下位ビットから最上位ビットまで右から左に移動すると、ビット 5 に到達するまで -35 の各ビットから +37 の各ビットを引くことができます (カウントは右側のビット 0 から始まります)。ビット位置 5 で減算する必要があるため、-35 のビット位置 6 (次の上位ビット)'1'
から'0'
借用する必要があります。これはたまたま'1'
借用の前になります。結果はこんな感じ
-35 decimal is 11011101 in two's complement 8-bit
+37 decimal is 00100101 in two's complement 8-bit
--------
-72 decimal is 10111000 in two's complement 8-bit
結果は負であり、8 ビットの 2 の補数の結果には上位ビットが設定されています (ビット 7)... これは負であるため、オーバーフローはありません。
更新:混乱がどこにあるかがわかると思います。ここでの答えは、2の補数の加算と減算が間違っていると主張しますdiscard the carry (indicates overflow)
。その答えでは、2 の補数を使用して 2 番目のオペランドを負に変換してから加算することにより、減算を行います。それは問題ありませんが、その場合、キャリーはオーバーフローを表していません。N ビット (0 から N-1 の番号) で 2 つの正の数を加算し、この符号なし算術演算を考慮range 0 to (2^N)-1
して、ビット位置 N-1 からキャリーアウトを取得すると、オーバーフローが発生します。つまり、2 つの正の数の合計 (符号なしとして解釈されます)表現可能な正の数の範囲を最大化するため)、最上位ビット (ビット N-1) のキャリーアウトを生成しないでください。したがって、2 つの正の数を加算すると、次のようにオーバーフローを識別します。
- 符号なしと解釈する場合、ビット N-1 のキャリーアウトがあってはなりません。
- 符号付き (2 の補数) として解釈される場合、ビット N-1 の結果はゼロでなければなりません。
ただし、プロセッサは符号付きと符号なしの加算/減算を区別しないことに注意してください...データを符号付きとして解釈している場合、結果を表すことができない(間違っている)ことを示すために、オーバーフローフラグを設定します。
ここでは、キャリーとオーバーフロー フラグの非常に詳細な説明を示します。その記事の要点はこれです
これはウィキペディアの算術オーバーフローの定義と一致しています。
ほとんどのコンピューターは、2 種類のオーバーフロー状態を区別します。キャリーは、オペランドと結果を符号なしの数値と見なして、加算または減算の結果が結果に収まらない場合に発生します。したがって、符号なしの値として解釈される数値を加算または減算した後にキャリー フラグをチェックすると便利です。結果がオペランドの符号から予測される符号を持たない場合、適切なオーバーフローが発生します (たとえば、2 つの正の数を加算したときの負の結果)。したがって、2 の補数形式で表される数値 (つまり、符号付き数値と見なされる) を加算または減算した後で、オーバーフロー フラグをチェックすると便利です。