C言語

2進数と16進数の基礎

ビットとバイト」では、コンピュータが「0」と「1」で情報を表していることを学びました。
しかし、「0」と「1」だけで、どうやって数を数えたり、容量を表したりできるのでしょうか。
今回は、コンピュータが使う数の表し方(2進数) と、それを読みやすくするための 16進数 について説明します。
この2つを理解すると、「なぜ1KB=1024バイトなのか」も自然にわかるようになります。

10進数の数え方(おさらい)

私たちが普段使っている数の表し方は 10進数 です。
0〜9 の 10種類の数字を使って、桁が上がるごとに10倍していきます。

つまり「123」は、(1×100) + (2×10) + (3×1) という計算で成り立っています。

2進数とは

2進数とは、2つの数字(0と1)だけで数を表す方法 です。
10進数では、「9の次が10」になりますが、2進数では、「1の次が10」になります。
つまり、桁が上がるたびに10倍ではなく、2倍になります。

それぞれの桁には 2のべき乗(2⁰, 2¹, 2², ...) の値が割り当てられています。

1桁目:20
2桁目:21
3桁目:22
4桁目:23

例えば、1101なら、

1桁目:1 × 20 = 1
2桁目:0 × 21 = 0
3桁目:1 × 22 = 4
4桁目:1 × 23 = 8
合計:13(10進数)

このように、2進数の各桁を足し合わせることで10進数に変換できます。

2進数と容量との関係

2進数では「桁が1つ上がる=2倍」なので、容量の単位(B, KB, MB, GB)は 2のべき乗 で増えていきます。
このため、1000 では2進数的に「桁がちょうど切れない」ため、扱いづらい。
そこで、「1キロ(K)」=1024 として定義した、というわけです。

1キロバイト(KB):1024バイト
1メガバイト(MB):1024KB
1ギガバイト(GB):1024MB

16進数とは

C言語では「メモリ」などを直接扱うことが多いです。
メモリアドレスや、ハードウェア制御でレジスタというものを扱う際、16進数表記が標準です。

16進数では、1桁で表せる数が 16種類(0〜15) になります。
10進数の「10」以上の数字は、アルファベットの「A〜F」を使って表します。
16進数の0~9は、10進数の0~9と同じです。10進数の10~15を16進数では、次のようになります。

10進数16進数
10A
11B
12C
13D
14E
15F

つまり、A〜F は「10〜15」を意味する記号 です。

2進数と16進数の関係

2進数は4ビット(0〜15)でちょうど16通りになります。
そのため、4ビット=16進数1桁 に対応します。

1111 11112進数)= 0xFF16進数)

となり、ずっと短く・見やすくなります。

C言語での使い方

C言語では、数値の前に 0x を付けると16進数になります。

int value = 0x3F;   // 16進数で「63」
int mask  = 0x0F;   // 下位4ビットを取り出すマスク

また、デバッガやデータシート、メモリアドレスなどは、
ほとんどが16進数表記 で書かれています。

#define PORTA  (*(volatile unsigned char *)0xFF00)

この 0xFF00 のような表記を理解するには、16進数の知識が欠かせません。

まとめ

  • 2進数は、0と1 の2つで数を表す(電気のON/OFFに対応)
  • 10進数は、0〜9 の10個で数を表す
  • 16進数は、0〜9とA〜Fを使い、2進数を短く表せる
  • 1KB=1024バイト は「2の10乗=1024」から生まれた
  • 容量の単位(KB, MB, GB)は、2のべき乗で決まっているため、2進数の考え方に基づいている
  • 16進数は、4ビット=1桁 の対応で、ビット構造を把握しやすい
  • 16進数は、C言語や組み込み開発では標準的な表記方法

-C言語