2進数・16進数入門 — コンピュータが数を扱うしくみ

私たちは普段 10進数で数を数えますが、コンピュータの内部はすべて 2進数(0 と 1)で動いています。そして、その2進数を人が読み書きしやすくまとめた表記が 16進数です。本記事では、まず「位取り記数法」という共通のしくみを押さえ、2進数・16進数(そして8進数)の考え方、相互変換の具体的な手順、255 = 11111111 = FF といった例までを、検算しながら正確に整理します。

結論を先に:どの記数法も「桁の重み」というたった一つの仕組みで説明できます。2進数は重みが …8 4 2 1、16進数は …256 16 1 と並ぶだけ。コンピュータが2進数を使うのは0と1の2状態が回路で確実に区別できるから、16進数を使うのは1桁がちょうど4ビットで2進数とぴったり対応するからです。

1. 位取り記数法 — すべての基本は「桁の重み」

10進数の 253 が「253」を意味するのは、各桁に重みがあるからです。右から順に 1(10の0乗)、10(10の1乗)、100(10の2乗)…と、桁が一つ上がるごとに重みが 10 倍になります。

例:253 = 2×100 + 5×10 + 3×1 = 200 + 50 + 3

この「桁が上がるごとに何倍になるか」を 基数(base / 底)と呼びます。10進数の基数は 10、2進数は 2、16進数は 16、8進数は 8 です。使う数字(記号)の種類は基数と同じで、10進数なら 0〜9 の 10 種類、2進数なら 0 と 1 の 2 種類です。

2. 2進数 — 0 と 1、ビット、なぜコンピュータは2進数なのか

2進数は基数が 2 で、使う数字は 01 の 2 種類だけです。桁の重みは右から 1, 2, 4, 8, 16, 32, 64, 128…2 倍ずつ増えていきます。2進数の 1 桁を ビット(bit)と呼び、8 ビットをまとめた単位が バイト(byte)です。

例:2進数 1101 を10進数に直すと

1101 = 1×8 + 1×4 + 0×2 + 1×1 = 8 + 4 + 0 + 1 = 13

なぜコンピュータは2進数を使うのか

コンピュータの中身は無数の電子回路です。回路の素子(トランジスタ)は、「電圧が高い/低い」「電流が流れる/流れない」という2つの安定した状態を区別するのが得意です。この 2 状態を 10 に対応させれば、数も文字も命令もすべて表現できます。

3. 16進数 — 0〜9とA〜F、1桁=4ビット

16進数は基数が 16 で、1 桁で 0〜15 の 16 通りを表します。10〜15 には数字がないため、A(=10)、B(=11)、C(=12)、D(=13)、E(=14)、F(=15)というアルファベットを当てます。桁の重みは右から 1, 16, 256, 4096…16 倍ずつです。

例:16進数 2F を10進数に直すと

2F = 2×16 + F×1 = 2×16 + 15×1 = 32 + 15 = 47

なぜ16進数が便利なのか — 色コードやメモリ表示

16 は 2 の 4 乗なので、16進数の 1 桁がちょうど 2 進数の 4 桁(4 ビット)に対応します。この 4 ビットのまとまりを ニブル(nibble)と呼びます。つまり 2 進数を 4 桁ずつ区切って 16進数に置き換えるだけで、長い 0/1 の列を 4 分の 1 の長さで表記できます。

4. 8進数にも少し触れておく

8進数は基数が 8 で、使う数字は 0〜7 です。8 は 2 の 3 乗なので、8進数の 1 桁は 2 進数の 3 桁に対応します。かつては 3 ビット単位が扱いやすい場面で広く使われ、現在も Unix/Linux のファイル権限(chmod 755 など)で目にします。

例:8進数 17 を10進数に直すと 1×8 + 7×1 = 8 + 7 = 15。ただし、現代のプログラミングでは 4 ビット単位の 16進数のほうが主流で、8進数の出番は限られます。

5. 相互変換の方法 — 手で計算してみる

基数どうしの変換は、いくつかの決まった手順で確実に行えます。代表的なものを、必ず検算しながら見ていきます。

10進数 → 2進数(割り算の繰り返し)

10進数を 2 で割り、余りを記録する作業を商が 0 になるまで繰り返します。最後に余りを下から上へ読むと 2進数になります。例:13 を 2進数へ。

余りを下から読むと 1101。検算:8+4+0+1 = 13 で一致します。

2進数 → 10進数(重みの掛け算)

各ビットに桁の重み(…8 4 2 1)を掛けて足すだけです。例:1101 = 8 + 4 + 0 + 1 = 13。これは上の割り算の逆操作になっています。

2進数 ↔ 16進数(4桁ずつまとめる)

ここが 16進数の便利なところです。2進数を右から 4 桁ずつ区切り、各 4 桁を 16進数 1 桁に置き換えます(足りなければ左を 0 で埋める)。例:11111111 を 16進数へ。

具体例でまとめ:同じ「255」という量は、基数を変えると次のように見えます。
10進数 255 = 2進数 11111111 = 16進数 FF = 8進数 377
検算:2進数 11111111 = 128+64+32+16+8+4+2+1 = 255。16進数 FF = 15×16 + 15 = 255。8進数 377 = 3×64 + 7×8 + 7 = 192+56+7 = 255。すべて 255 で一致します。

0〜15 の対応を一覧にすると、2進数・16進数の関係(4 ビット = 1 桁)がよく見えます。

10進数2進数(4桁)16進数
000000
100011
200102
300113
401004
501015
601106
701117
810008
910019
101010A
111011B
121100C
131101D
141110E
151111F

6. 負数とビット幅 — もう一歩だけ深く

ここまでは 0 以上の数(非負整数)だけを扱いました。実際のコンピュータでは、値を入れる「箱」の大きさ=ビット幅があらかじめ決まっています。8 ビット、16 ビット、32 ビット、64 ビットなどです。8 ビットなら表せるのは 0〜255 の 256 通り(2 の 8 乗)です。

2 の補数や浮動小数点(小数の表し方)は、それ自体が一つのテーマになるほど奥が深いので、ここでは「ビット幅と解釈によって意味が変わる」というところまで押さえれば十分です。

Free Tool 基数変換ツールで実際に変換する 10進数・2進数・16進数・8進数を相互に変換できます。本文の例(255 = 11111111 = FF = 377)も、その場で入力して確かめられます。

よくある質問(FAQ)

なぜコンピュータは2進数を使うのですか?

コンピュータの基本部品であるトランジスタやメモリ素子は「電圧が高い/低い」「電流が流れる/流れない」といった2つの安定した状態を確実に区別するのが得意だからです。状態が2つなら、わずかなノイズがあっても0と1を取り違えにくく、回路を単純で高速・安価に作れます。10通りの電圧レベルを正確に区別するより、2通りを区別するほうがはるかに信頼性が高いため、内部表現には2進数が使われます。

16進数はなぜ使うのですか?

16進数の1桁がちょうど4ビット(2進数4桁)に対応し、2進数と相互変換しやすいからです。長くて読みにくい2進数を、4桁ずつまとめて短く表記できます。たとえば8ビット(1バイト)は16進数2桁で表せます。メモリダンプ、色コード(#RRGGBB)、文字コード、MACアドレスなどで、人が読み書きしやすい表記として広く使われています。

なぜ255は16進数でFFになるのですか?

16進数では1桁で0〜15を表し、Fが15を意味します。FFは上の桁が15×16=240、下の桁が15で、合わせて240+15=255になります。255は8ビットで表せる最大値(2進数では11111111)であり、ちょうど16進数2桁の最大値FFと一致します。このため1バイト=16進数2桁という対応が成り立ち、色コードなどで255がFFとして現れます。

← 技術ブログ一覧へ戻る