CS の続きで補数表現のはなし
CREATED: 2026 / 05 / 07 Thu
UPDATED: 2026 / 05 / 07 Thu
補数とは
補数とは何かと聞かれても正直抽象的な説明文に落とし込むことができないのですが、僕が思うにこれは以下を達成するためのツールだと思ってます👀
- 限られたデータ長の中でマイナスの数を表現するため
- 引き算を足し算として扱えるようにするため
歴史的にこれがどのように使われてきたかはわかってませんが、引き算を足し算として扱えるようにするためっていうのはどこか後付けな感じがするのは僕だけでしょうか🤔
マイナスの数を表現するために考えられたものがうまいこと引き算を足し算として扱えるじゃんとなっただけなんじゃなかろうかと。
まあ、その逆もあり得ますが、、、
2 進数における補数には 1 の補数表現と 2 の補数表現がありますのでそれぞれ考えたいと思います。
なのでここでは 2 進数の補数についてのみ書いてます(10 進数には 10 の補数と 9 の補数があります)。
1 の補数表現
1 の補数は各ビットを反転することで得られます。
例えば、4 bits を上限とする範囲における 0101(2) の 1 の補数は以下のようになります👇
0101 → 各ビットを反転 → 1010
よって、0101(2) は 5(10)、1010(2) は -5(10) となります。
4 bits 空間における 1 の補数の表現範囲は以下の通りです。 ちなみに、補数表現では、最上位のビットが 0 なら正の数、1 なら負の数としてあつかわれます。
| 2 進数 | 10 進数 |
|---|---|
| 0111 | +7 |
| 0001 | +1 |
| 0000 | +0 |
| 1111 | -0 |
| 1110 | -1 |
| 1000 | -7 |
このように補数表現は何も全ての数値を表現するためのものではなく、ある限られた空間(上記で言えば 4 bits の空間)内で正の数のみならず負の数も表現するためのテクニックといえます。
これは特にシステムにおける有限な資源上(有限なメモリ空間)で値の表現力を広げるために利用されます。
その上引き算を足し算として扱えるので処理も楽になります👀
ただ、1 の補数表現では上の表のように、0000 は +0、1111 は -0 を意味し、同じ「0」に 2 つの表現が存在してしまってます。
こういうこともあって、1 の補数表現は一般的に現代のコンピューターではほぼ使われず、代わりに 2 の補数表現が使われています。
2 の補数表現
2 の補数は 1 の補数に 1 を加えることで得られます。
2の補数 = 1の補数 + 1
たとえば、4 bits を上限とする範囲における 0101(2) の 2 の補数は以下のようになります👇
0101(2)
↓ 各ビットを反転(1の補数)
1010(2)
↓ 1を加算
1011(2)
よって、0101(2) は 5(10)、1011(2) は -5(10) となります。
4 bits 空間における 2 の補数の表現範囲は以下の通りです。
| 2 進数 | 10 進数 |
|---|---|
| 0111 | +7 |
| 0001 | +1 |
| 0000 | 0 |
| 1111 | -1 |
| 1110 | -2 |
| 1000 | -8 |
+0 と -0 のダブりが解消され、0 は 0000 の 1 通りだけになりました。
ちなみに、n ビットで表現できる範囲は -2^(n-1) 〜 2^(n-1) - 1 となります。
4 bits の場合は -8 〜 +7 です。
補数の利点
再度触れますが、補数を使うことの利点は以下のとおりです。
- 限られたデータ長の中でマイナスの数を表現するため
- 引き算を足し算として扱えるようにするため
マイナスの数を表現するためっていうのは上で話したことからその便利さがわかるかと思うので、ここでは後者の方に触れてみようと思います。
引き算を足し算として扱えるようにするため
通常の計算では A - B を直接行いますが、補数を使うと次のように変換できます。
A - B = A + (-B)
-B は B の補数に相当します。
たとえば、5 - 3 を 4 bits 空間 の 2 進数で計算してみると、
5 = 0101(2)
3 = 0011(2) → 2の補数 → 1101(2)
0 1 0 1 (= 5)
+ 1 1 0 1 (= -3)
---------
0 0 1 0 (= 2、最上位からの繰り上がりが起きてますが、4 bits 空間の計算なのではみ出た分は無視します)
10 進数で確認すると、5 - 3 = 2 となるのであってますね👀
を仕舞い
近々数学についてのタグも切ろうと思います。
3DCG でつかう三角関数とかまとめたいなと🤔