矢沢久雄

 10進数の6は,2進数で0110になります。それでは,10進数の-6を2進数で表すとどうなるでしょう。-0110でしょうか?いいえ違います。なぜなら,0と1の2種類の情報しか表せないコンピュータには,マイナス符号(-)を表す手段がないからです。0と1とマイナス符号では,3つの情報になってしまいます。そこで,コンピュータは「マイナスの数をプラスの数で表す」という何とも不思議な表現方法を使っているのです。

●マイナスをプラスで表す補数

図1●ピンの数を超えた桁上がりは無視される
 マイナスの数をプラスの数で表す表現方法を「補数(ほすう)」と呼びます。2進数の前に,10進数で補数の考え方を説明しましょう。ここでは,10進数で5-3という引き算をするとします。5-3は,5+(-3)と同じですね。-3を補数で表すと,つまり-3をプラスの数で表すと7になります。5+7を計算してください。

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を引く効果がある
 「この説明ではピンとこない」という人のために,補数の関係を,もっと分かりやすいイメージで示しましょう。5-3という計算において-3は,5から3を引こうとしているわけですね。「オレは5から3を引きたいよ~」と思っているのです(あくまでもイメージです)。5+7という計算における7はどうでしょう。5に7を足そうとしているわけですが,7が「ボクは5から3を引いて10に桁上がりしたいよ~」と思っているとも言えますね。皆さんだって,5+7を計算するときに,5を2と3に分けて,その3を7に足して10としてから,10に2を足して答えは12と考えることがあるでしょう。「まだピンとこない」という人は,納得するまで図2[拡大表示]を見てください。

●2進数の補数表現

 2進数でも補数の考え方は,10進数と同様です。「足すことによって桁上がりする数」が補数です。何桁目を桁上がりとするかを決めた上で,補数を求めることになります。ここでは,8桁(8ビット)の2進数0000 0110(10進数で6)の補数を求めてみましょう。

図3●2進数の各桁を反転させ,その結果に1を加えと,補数を求められる
 2進数の補数は,2進数の各桁を反転させ(0を1に,1を0にする),その結果に1を加えることによって求められます。これを「反転して1」と覚えます(図3[拡大表示])。

 0000 0110の補数が1111 1010であることがわかりました。0000 0110を10進数で表すと6ですから,補数である1111 1010は10進数の-6を表していることになります。

 「足すことによって桁上がりする数」が補数であるわけですが,どうして「反転して1」によって「足すことによって桁上がりする数」が求められるか,その理屈を理解してください。コンピュータの世界は,丸暗記ではいけません。何事も理屈を知らなければ,コンピュータと仲良くなれません。

 もとの数0000 0110に反転した数1111 1001を足すと,両者は0と1のパターンが逆なので,結果としてすべての桁が1111 1111になります。それなら,もとの数0000 01101111 1001より1大きい数を足したらどうなるでしょう。1111 1111に1を足す結果になるので,9桁目に桁上がりすることになりますね。したがって,「反転して1」によって「足すことによって桁上がりする数」が求められるわけです。

図4●0000 0110の補数1111 1010は-6
 0000 0110の補数である1111 1010が-6を表していることを確認しておきましょう。ここでは,10進数の10-6=4という計算を2進数でやってみます。2進数の桁数は,8桁にします(図4[拡大表示])。確かに4という答えが得られていますね!

●符号ビットと絶対値

 そもそもコンピュータには,マイナスの数という概念はありません。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 00001111 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だけしか表せないコンピュータには,小数点(.)を表す手段もありません。そこで,ちょっとトリッキーな方法が使われています。それは何か?…請うご期待です!