以下とても素晴らしい質問が来たので、長々と解説してしまいました。が、補数について疑問に思わなかったり、読みたくなければ読まなくて結構です。
【質問】(一部抜粋)質問です。 十進数の-9を2進数で表すとどうなるのですか? (略)-8より小さい数または7より大きい数を2進数で表す方法がわからないです(左端1ビットを符号部とする場合)。 十進数における-8より小さい数または7より大きい数を2進数で表現するとどうなるのか考えましたが、符号部を除いて4桁になってしまうので、どこに符号部をつけるのかわかりません。(Sさん)
【回答】大変すばらしい気付きです!!ありがとう!!!結論から言うと、「(二進法4bit/4桁の補数表現では)-8より小さい数や+7より大きい数は表せません」。
十進法で説明すると、十進法一桁で、符号を使わずに補数による負の数を考えたばあい「-5~+4」しか表せないので「+7」などは無理、ということになります。今回の補数は十進法で説明します。
「補数」とは何か、十進法で説明します。
補数は結構みんな普通に使っていて、
7←→3
8←→2
のように足したら「10」になる相手の数値だったり、
72←→28
64←→36
のように足したら「100」になる相手の数値。
あといくつ足せばちょうどピッタリになるのかという数値ことを補数と言います。暗算するときに考えますよね。
補数を使うと、引き算が足し算でできる、という利点があります。ん?引き算が足し算でできる???
ある数xの補数の作り方を示します。
何桁か決める
その桁最大値からxを引く
1を足す
この手順は覚えてくださいね!
さっそくやってみましょう。2という数値があるとします。この補数を考えてみます。まず、一桁で考えてみます。2にあといくつ足せばピッタリになるか。8です。すぐにわかります。が、一応上記の手順に従ってやってみると、①一桁とする、②一桁最大値は9だから9-2=7、③7+1=8。ということで8ですね。
2+8=10 ピッタリ!
ということで、「8は2の補数である」という言い方をします。この時、8は「-2」と同じ働きをする数値として扱うことができます。どういうことか。試しに3引く2という引き算を足し算で考えてみましょう。
3-2=3+(-2)
ここで、-2と同じ働きをする8に置き換えると、
3-2=3+(-2)=3+8=11
となりますね。最初に「一桁で考えてみます」と書きましたが「11」は二桁です。十の位は桁あふれとして無視します。
3-2=3+(-2)=3+8=11→(二桁目の10を無視して)→1
∴3-2=1
はい。引き算を足し算で計算できました。……わかりました?
同様に4引く2でやってみると
4-2=4+(-2)=4+8=12→(10を無視して)→2
∴4-2=2
ですね。
では2桁で考えてみます。2という数値の補数はいくつになるか。①二桁で、②二桁最大値は99だから99-2=97、③97+1=98。
2+98=100 ピッタリ!
「98は2の補数である」と言えます。この98は「-2」と同じ働きをします。
37-2=37+(-2)=37+98=135→(二桁なので100を無視して)→35
∴37-2=35
できました。他の計算もいろいろやってみてください。
さて、2に対する補数、さっきは「8」でこんどは「98」でどっちなの?と思った方もいると思います。どちらも補数の候補としては正解なわけなのですが、8でも98でもどっちでもOK!というわけではありません。ポイントは「①何桁か決める」です。補数を考えるうえで、何桁でのことなのかがまず最初にあります。「2」の補数は、一桁なら「8」、二桁なら「98」、三桁なら「998」です。
十進法一桁で表せる範囲はー5~+4ということになります。
符号→補数表現
+4→4
+3→3
+2→2
+1→1
0→0
-1→9
-2→8
-3→7
-4→6
-5→5
すると、+7や-6はどうなるの?と思いますが、一桁では表せません。二桁使ってください、ということになります。つまり範囲の半分消えちゃいます。もったいない!と思うかも知れませんがその分、負の数を符号無しで表すことができたわけです。実は範囲がずれただけで消えたわけではありません。以下の図を見てください。
0~9で一回転している円盤があります。10が0に戻ります。-2ということは左回りに2目盛ですが、右回りに8目盛進んだところと同じ位置になります。つまり+8はー2と同じ意味です。これこそ補数ですね?!4-2という計算は4の目盛から左回りに2戻る代わりに、右回りに8進んでも同じ「2」の位置にくるわけです。
一桁では円盤が十等分ですが、二桁では円盤が百等分になり、-2と98が同じ位置に来ることがわかると思います。
「8」と言われたらそのまま「+8」と受け取っていいのか、「-2」のように補数で考えるのか。それは「いま何桁で考えているのか」という前提を思い出し、一桁の補数表現では「-2」、二桁以上なら「+8」ということになります。
最初の質問の二進法の補数にも一応触れておくと、4bitでは「0000~0111」までが十進法で+0~+7、「1000~1111」までは十進法で-8~-1になります。最上位bit(一番大きな位、つまり左端)が「0」ならば正の値、「1」ならば負の値ということが分かるので、この位を「符号部」と呼んでいます。ということで、4bitで表せるのは-8~+7の間。その範囲を出るなら、5bit以上必要になります。
さて、補数を使うと何がうれしいのかというと、負の数を符号を使わずに表現することで、引き算を足し算に置き換えることができる、ということです。引き算をしないということは上の位から借りてくるメンドウがなくなることを意味します。これはコンピュータにおいては非常に助かります。