1.6.3 符号つき整数演算 / 非公式訳

要するにたとえば符号つき4ビット整数は範囲が-8~7なので、4+4=8 (0b1000)は範囲を超えるためオーバーフローは発生するがキャリーアウトは発生しない。6-2=4は範囲を超えないのでオーバーフローは起きないが0b0110+0b1110=0b10110なのでキャリーアウトが発生する。

pp.19-20

非公式訳:
Nビット符号つき整数の範囲は-2N-1~2N-1-1です。たとえばN=4の場合は-8~7です。符号つき整数の値を変えずにビット数を増やすためには、元のMSBを元の値の上位ビットに連ねる必要があります。これを「符号拡張(sign extension)」といいます。たとえば0111000000000000111100011111111111000になります。

負数は一般に2の補数形式で表現します。したがって、或数から或数を引くときは、引く数を2の補数にしてからそれをもう一方の数に足すだけで済みます。回路の視点でいえば、2の補数を得るための最も簡単な方法は、すべてのビット値を反転してそれに1を加えることです(図1.16の回路を思い出してください)。

人間の視点で比較的簡単な方法は、与えられた10進数の負数を2Nに加算することです。たとえば-13をN=5ビットで表現する場合は25-13=19 (=0b10011)という計算をします。したがって-13=0b10011です。逆に負の2進数値に相当する10進数値を求めるときはちょうど逆の操作をすればよい。つまり、全ビットを反転して1を加え、さらにマイナス符号を添えます。たとえば、0b10011の10進数値は、-(12+1)=-13です。

Nビットの符号つき整数(正負問わず)を2つ加算するときは、オーバーフローを防ごうとすれば加算結果用にN+1ビットが必要です。Nビットしかない場合はオーバーフローが起きえます。上記の定義と2の補数形式で入力された負数とに従ってキャリーアウトビット、オーバーフローフラグ、加算結果の新たなMSBを求める基準について以下に簡単にまとめました。

キャリーアウトビット(cout): 最終段の内部キャリービットのことです(訳註: [3:0]ビット同士の加算なら、ビット[3]の全加算器から出るキャリーのこと)。オペランドだけでも判定できます。両オペランドのMSBが1である場合、または両オペランドのMSBは異なるが加算結果の元のMSB (訳註: [3:0]ビット同士の加算なら、加算結果のビット[3]のこと)が0である場合は、cout=1です。

オーバーフローフラグ(oflow): オーバーフローはキャリービットだけで判定できます。最後の2つのキャリービット(訳註: [3:0]ビット同士の加算なら、ビット[3]およびビット[2]からでるキャリーのこと)が違っていればoflow=1です。またオペランドだけでも判定できます。両オペランドのMSBは同じであるがその値が加算結果の元のMSB (訳註: [3:0]ビット同士の加算なら、加算結果のビット[3]のこと)と違っている場合はoflow=1です。

加算結果の新たなMSB [s(N)]: (訳註: [3:0]ビット同士の加算なら、加算結果のビット[4]のこと)両オペランドのMSBが等しい場合、s(N)はcoutに等しい。両オペランドのMSBが異なる場合、s(N)を得るためにはcoutを反転しなければなりません。

s(N)が与えられてcoutを求める場合: 両オペランドのMSBが等しい場合、coutはs(N)です。両オペランドのMSBが異なる場合、coutを得るためにはs(N)を反転しなければなりません。

上の説明から導かれる数式を図1.22aの表にまとめました。またそれに相当するトップレベル回路図を図1.22cに示しました。数値の例は図1.24に示しました。

左シフトによる掛け算、および右シフトによる割り算は、符号なし整数についての説明と同じです。ただし割り算は、論理シフトではなく算術シフトで実行します(つまり右シフトで空いたビットは、元のオペランドのMSBで埋めるということです)。これについては、図1.25a (正数00101 (=5)の場合)、および図1.25b (負数11010 (=-6)の場合)に示しました。左シフトの場合は間違った結果になることがありますが、図1.25a、図1.25bでそうなっていないのは、都合の良い値を選んだからに過ぎません。(以下略)