基本情報技術者試験などでおなじみの「1の補数」や「2の補数」といった補数表現について、今回はそれぞれの仕組みと、計算方法についてご紹介したいと思います。
1. 補数表現とは?
1.1 補数表現とは
「補数(complement)」とは、「元の数」と「補数」を足した場合に桁上がりが発生する数のうち「最小」の数のことです。
さらに補数には、「減基数」という考え方があります。こちらは「元の数」と「補数」を足すと桁上がりが発生しない数のうち、「最大」の数が補数となります。
補数といえば一般的には2進数の「1の補数」と「2の補数」が有名ですが、実は全ての「n進数」に補数という概念が存在します。例えば普段使っている10進数にも、「10の補数」と、減基数の「9の補数」が存在します。8進数ならそれぞれ「8の補数」と「7の補数」です。つまりn進数の補数表現には、それぞれ「nの補数」と「(nー1)の補数」が存在するのです。このnは「基数」であり、(n-1)は「減基数」です。
言葉で説明するのは難しいので、実際に10進数で補数を求めてみます。
まず10進数の「10の補数」の場合、お互いに足したら桁が上がる最小の数は10のべき乗です。例えば元の数が1桁であれば10の1乗、3桁であれば10の3乗つまり1000が「元の数」と「補数」を合計した数になります。
・「6」の補数は「4」 (10¹=10)
・「171」の補数は「829」 (10³=1000)
一方「9の補数」の場合、お互いに足しても桁が上がらない数の最大値は、10のべき乗から1を引いた値になります。元の数が1桁であれば10-1=9、3桁であれば1000-1=999が「元の数」と「補数」を合計した数になります。
・「6」の補数は「3」 (10¹-1=9)
・「171」の補数は「828」 (10³-1=999)
なおこの例では基数10のため合計数を10のべき乗で計算していますが、これは他の基数であっても共通の式で表すことができます。
・基数の場合の合計数 = nのm乗
・減基数の場合の合計数 = nのm乗-1
※n進数、かつ元の数の桁数をm桁とする
1.2 補数表現を使うメリット
補数を使うことによってもたらされる最も大きなメリットは、「マイナス記号を使わずに負の数を表現することができる」という点です。
例えば、次のような計算をしたいとします。
1195-171=1024
ところがこの引き算という概念が使えない場合、足し算で同じ計算を行う方法があります。それに活用できるのが10の補数です。
今回は最大4桁の数を計算に使うので、「10000」がベースとなります。よって171の補数は、「9829」です。ここで「171」を引く代わりに、この「9829」を足してみます。
1195+9829=11024
この結果から最上位の桁にある「1」を取り除くことで、答えである「1024」を得ることができました。
常に上手くいくのか不思議に思われるかもしれませんが、式を分解してみると次のようになります。
1195+(10000-171)=10000+1024
このように両辺からそれぞれ+10000を取ると、元の式のままであることが分かります。
1.3 1の補数と2の補数の違い
前項まででお察しの通り、1の補数と2の補数の違いはそれぞれ基数を使用するか減基数を使用するかという点だけであり、基本となる考え方は同じです。2つの異なる点は、その用途になります。
ここから先は補数の中でも特に情報処理の世界でお世話になることの多い「2進数の補数表現」にスポットをあてて、詳しくご紹介していきたいと思います。
2. 1の補数の計算方法
2.1 1の補数とは
2進数の1の補数とは、(n-1)の補数、つまり減基数を使った補数です。2進数である元の数とこの補数を足し合わせると、10進数の9の補数のケースと同じく、桁が上がらない状態で最も大きな値になります。
2.2 1の補数の計算方法
1の補数を求めるには実はとても簡単な方法があるのですが、まずは基本の手順を踏んで求めていきたいと思います。
今回は、元の数を7桁の2進数「1001101」とします。
項目1.1の式に当てはめると、この場合n=2、m=7であることから、減基数である1の補数の合計数は
2の7乗-1=127
この「127」をを2進数に変換すると「1111111」になるので、
1111111-1001101=0110010
となり、よって1の補数は「0110010」と求められます。
この結果を見てピンときた方も多いかと思いますが、元の数と補数を並べてみると
元数:1001101
補数:0110010
このように、元の数の0と1を反転したものが1の補数となっていることが分かります。つまり計算しなくても0と1を入れ替えるだけで、1の補数は求めることができるのです。
2.3 1の補数の使い道
0と1が完全に反転することから、コンピュータ上で「ビット反転」の処理をしたい場合に使用することができます。
3. 2の補数の計算方法
3.1 2の補数とは
2進数の2の補数とは、nの補数、つまり基数を使った補数です。2進数である元の数とこの補数を足し合わせると、10進数の10の補数のケースと同じく、桁が1つ上がります。
3.2 2の補数の計算方法
2の補数を求める方法について、こちらにもとても簡単な方法がありますが、1の補数と同じくまずは基本の手順を踏んでいきたいと思います。
先ほどと同じく、元の数を7桁の2進数「1001101」とします。
項目1.1の式に当てはめると、この場合n=2、m=7であることから、基数である2の補数の合計数は
2の7乗=128
この「128」をを2進数に変換すると「10000000」になるので、
10000000-1001101=0110011
となり、よって2の補数は「0110011」と求められます。
今回も結果を見てピンときた方がいらっしゃるかと思いますが、前項で求めた1の補数と並べてみると
1の補数:0110010
2の補数:0110011
つまり、1の補数に1を足したものが2の補数であるということが分かります。
これも考えてみると単純で、引き算の引かれる数が2の補数の方がもともと1多いので、引く数が同じなら結果も1多くなるというだけです。
まとめると、2の補数を求める最もかんたんな手順は次のようになります。
(1)元の数の0と1を入れ替える
(2)入れ替えたものに、1を足す
3.3 2の補数の使い道
項目1.2でも述べたように、2の補数を用いることで「引き算」を「足し算」で表すことができます。ビット反転、足し算共に、コンピュータで様々な機能を実現するためにはなくてはならない考え方です。
4. 補数の本領発揮はビット操作
補数表現のメリットとして引き算を足し算にすることができると書きましたが、普通に引き算すればいいのにわざわざ面倒な計算を増やす必要なんてあるの?と思われるかもしれません。しかしビット操作で成り立っているコンピュータにとっては、とても大事な考え方なのです。
初心者のうちはあまり実戦での親しみはないかと思いますが、より高度なプログラミングに挑戦するようになるといずれお世話になるかもしれません。試験対策の計算丸暗記だけでなく、ぜひ補数の仕組みを覚えておいて下さいね。
当サイトプロエンジニアのコンサルタントが厳選したおすすめのフリーランス案件特集はこちら
特集ページから案件への応募も可能です!
実際にフリーランスエンジニアとして活躍されている方のインタビューはこちら