矢沢久雄
10進数の6は,2進数で0110になります。それでは,10進数の-6を2進数で表すとどうなるでしょう。-0110でしょうか?いいえ違います。なぜなら,0と1の2種類の情報しか表せないコンピュータには,マイナス符号(-)を表す手段がないからです。0と1とマイナス符号では,3つの情報になってしまいます。そこで,コンピュータは「マイナスの数をプラスの数で表す」という何とも不思議な表現方法を使っているのです。
●マイナスをプラスで表す補数
![]() |
図1●ピンの数を超えた桁上がりは無視される |
5+7=12
答えは12になります。このとき「桁上がりを無視する」というルールを定めると,5+7=2
となります。これは,確かに5-3=2の答えと合っています。なんとも狐につままれたような話ですが,マイナスの数-3をプラスの数7で表すことができたのです。ポイントは「桁上がりを無視する」ということです。これが,コンピュータの仕組みに上手くマッチします。コンピュータは,ICのピンの数に応じて,計算できる桁数が限られています。例えば,8本のピンで情報を取り扱うコンピュータなら,計算結果が8桁を超えたら(9桁目に桁上がりしたら),桁上がりした部分は無視される(情報が捨てられる)しかありません。この性質を使って,コンピュータでは補数でマイナスの数を表しているのです。例えば,図1のように1 0000 0000という9桁の2進数は,8本のピンのICでは0になります。最上位桁の1を入れるピンがないからです。
10進数の場合は,-3と7の関係のように絶対値(符号を考えない値)を足すと10となる(桁上がりする)関係にある数が補数となります。-3の絶対値は3です。3に足すと10となる数は7です。だから,-3の補数は7なのです。
![]() |
図2●7には3を引く効果がある |
●2進数の補数表現
2進数でも補数の考え方は,10進数と同様です。「足すことによって桁上がりする数」が補数です。何桁目を桁上がりとするかを決めた上で,補数を求めることになります。ここでは,8桁(8ビット)の2進数0000 0110(10進数で6)の補数を求めてみましょう。
![]() |
図3●2進数の各桁を反転させ,その結果に1を加えと,補数を求められる |
0000 0110の補数が1111 1010であることがわかりました。0000 0110を10進数で表すと6ですから,補数である1111 1010は10進数の-6を表していることになります。
「足すことによって桁上がりする数」が補数であるわけですが,どうして「反転して1」によって「足すことによって桁上がりする数」が求められるか,その理屈を理解してください。コンピュータの世界は,丸暗記ではいけません。何事も理屈を知らなければ,コンピュータと仲良くなれません。
もとの数0000 0110に反転した数1111 1001を足すと,両者は0と1のパターンが逆なので,結果としてすべての桁が1111 1111になります。それなら,もとの数0000 0110に1111 1001より1大きい数を足したらどうなるでしょう。1111 1111に1を足す結果になるので,9桁目に桁上がりすることになりますね。したがって,「反転して1」によって「足すことによって桁上がりする数」が求められるわけです。
![]() |
図4●0000 0110の補数1111 1010は-6 |
●符号ビットと絶対値
そもそもコンピュータには,マイナスの数という概念はありません。0と1だけの世界だからです。例えば1111 1111という8桁の2進数は,10進数でいくつか?と聞かれたら,255と答えるのが自然でしょう。ただし,桁あふれを無視するという性質によって,1111 1111は10進数で-1だと考えることもできるのです。これは,10進数の7を3を引く数と考えることができるのと同様です。
1111 1111が255を表していると見ても,-1を表していると見ても,計算結果は正しくなります。コンピュータにしてみれば,同じ電気信号だからです。1111 1111を255と見て,それに1を足してみましょう。結果は,9桁目に桁上がりして0になります。桁があふれて0になったのです。1111 1111を-1と見て,それに1を足してみましょう。結果は,-1+1=0となります。どちらの結果も同じです。
8桁の2進数0000 0000~1111 1111は,補数表現でないと見れば10進数の0~255となります。補数表現であると見れば,-128~127となります。補数表現の場合は,最上位桁(8ビット目)が1であればマイナスの数を表し,0であればプラスの数を表します(人間の目から見てです)。このことから,最上位ビットを「符号ビット」と呼ぶことがあります。
例えば,補数表現の0111 1010は,10進数でいくつになるかすぐには分からなくても,符号ビットが0なのでプラスの値であることがわかります。補数表現の1111 0001なら符号ビットが1なので,マイナスの値です。
それでは,1111 0001は10進数でマイナスいくつになるのでしょう?ここで,マイナスのマイナスはプラスだということを思い出してください。例えば-(-123)=123ですね。1111 0001は,符号ビットが1なのでマイナスの値ですが,その値(絶対値)は1111 0001を「反転して1」した0000 1111つまり10進数で15となります。したがって,1111 0001は10進数の-15です。「反転して1」は,プラスの数のマイナス表現を求めることも,マイナスの数の絶対値(マイナスのマイナスはプラスだから)を求めることもできるのです。
最後に,もう1つだけ問題です。補数表現の32ビットの2進数1111 1111 1111 1111 1111 1111 1111 1111は,10進数でいつくでしょう。答えは,-1です。符号ビットが1なので,マイナスの値です。その値は,1111 1111 1111 1111 1111 1111 1111 1111を「反転して1」で0000 0000 0000 0000 0000 0000 0000 0001で1です。このように,何桁であっても「すべての桁が1である2進数は-1を表している」ということをコンピュータの常識のひとつとして覚えておいてください。
次回は,2進数で小数点数を表す方法を説明します。ご想像のとおり,0と1だけしか表せないコンピュータには,小数点(.)を表す手段もありません。そこで,ちょっとトリッキーな方法が使われています。それは何か?…請うご期待です!