2進数と2の補数
2進数の乗算(掛け算)
2進数での掛け算も10進数と同様、筆算での計算が可能。
例) 5 * 3 = 15
0101 = 5
x 0011 =
3
0101
0101
0000
0000
0001111 = 15
2進数の除算(割り算)
これもまた筆算での計算が可能。
例) 13 / 3 = 4 ... 1
100 = 4
11 / 1101
11
1 = 1
2進数での負数の表示
1) 絶対値法
絶対値法とは、ある負の数を表示する場合に、先頭ビットを符号ビットとし、残りのビットを仮数部として数値を表示する方法である。
例) -3: 1 | 0101 (5ビット表示で、先頭1ビットが符号ビット)
この表示法の欠点は、
l 負数の足し算がそのままでは出来ず、減算(引き算)として処理しなくてはいけないこと ( 5 + (-3)を、5 -3 として計算する必要がある)
l 0が0 | 0000と1 | 0000の二通り表現できてしまうところ
である。絶対値法により表現できる範囲は、5ビットの場合、-15~0、0~15となる。
2) 1の補数
1の補数とは、ある負の数を表示する場合に、その正の数の値のビットを全て反転して表示する方法である。(ただし、先頭ビットは符号ビットとみなす)
例) -3:
まず、3は 0 | 0011 なので、これをビット反転表示し、
-3: 1 | 1100 (5ビット表示で、先頭1ビットが符号ビット)
この表記法は、絶対値法の最初の欠点である負数の足し算の問題を解決する。つまり、負の数の加算(足し算)をそのまま加算として処理できるのである。ただし、ちょっとした工夫がいる。
例)5 + (-3) = 2
5:0 | 0101
+ ) -3:1 | 1100
10 | 0001
ただし、このままでは合わないので1の補数の加算の場合、この桁あふれした1(キャリー)を結果に加えてやる必要がある。そうすると、
0 | 0001 + 0 | 0001 = 0 | 0010(=2) となって、正解が得られる。
ただし、1の補数は絶対値法の2番目の問題である0の表示が二通りあるという問題を解決しない。1の補数により表現できる範囲は、5ビットの場合、-15~0、0~15となり、絶対値法と変わらない。
3) 2の補数
そこで登場するのがこの2の補数である。2の補数とは、ある負の数を表示する場合に、その正の数の値のビットを全て反転し、それに1を加えて表示する方法である。(ただし、1の補数と同様、先頭ビットは符号ビットとみなす)
例) -3:
まず、3は 0 | 0011 なので、これをビット反転表示し、
1 | 1100 (5ビット表示で、先頭1ビットが符号ビット)
これに1を加えて、
-3: 1 | 1101
2の補数も負数の足し算の問題を解決する。さらに1の補数の際に行った工夫さえ必要ない。
例)5 + (-3) = 2
5:0 | 0101
+ ) -3:1 | 1101
0 | 0010 (=2)
この方法の場合、0は0 | 0000としかならない。では、1の補数では同じく0を意味していた1 | 0000は2の補数では何を意味するのであろうか?これを求めるには、2の補数を求める場合の逆を行えばいよい。即ち、1を引いて、ビットを反転したら何になるのかを考えればよい。
1 | 0000 → 0 | 1111 → 1 | 0000
(1を引く) (反転表示)
見たところ、同じ数字に戻ってしまったが、元々負の数をビット反転表示したので現時点ではこれは正の数を表示していると捉えれば、これは16になる。
よって、元の1 | 0000は、絶対値が16、また先頭ビットは1であったので、符号はマイナスとすれば、これは-16とするのが妥当となる。
よって、2の補数では、0の表現が重複してしまうという問題を解決し、表現できる範囲はこれまでの表現法と比べ1増えて、5ビットの場合、-16~15となる。
オーバーフロー
補数表示による加算減算にはオーバーフローがつき物だが、これには以下のロジックを設けることで対応する。
l 符号が同じもの同士の加算で結果の符号が予想と異なる場合
(+)+(+)=>(−)、(−)+(−)=>(+)
l 符号が異なるもの同士の減算で結果の符合が予想と異なる場合
(+)−(−)=>(−)、(−)−(+)=>(+)
注)なお2の補数表示であっても、乗算と除算は絶対値で計算し、最後に符号を考慮する。