🔢
数の体系:2進数・16進数・ASCIIからUnicodeへ
10進数が「指が10本」だからという話から始まり、2進・8進・16進の変換方法、バイト・ASCII・UTF-8まで。なぜコンピュータが16進数を好むかも解説。CODE第2版 Ch.9-13。
なぜ10進数を使うのか
答えは単純:人間の指が10本だから。
数学的に10という数に特別な意味はない。指が8本なら8進数が「自然な数え方」になっていた。
位取り記数法の原理(基数 n の場合):
各桁 = (0 〜 n-1) の値 × n^(桁の位置)
10進数 342 の意味:
3 × 10² + 4 × 10¹ + 2 × 10⁰
= 300 + 40 + 2 = 342
この原理はどの基数でも同じ。
2進数(基数2)
使う数字:0 と 1 だけ。
2進数 → 10進数 への変換:
1 1 0 1 (2進)
↑ ↑ ↑ ↑
8 4 2 1 ← 2の累乗(右から 2⁰, 2¹, 2², 2³)
1×8 + 1×4 + 0×2 + 1×1 = 13 (10進)
10進数 → 2進数 への変換(繰り返し2で割る):
42 ÷ 2 = 21 余り 0
21 ÷ 2 = 10 余り 1
10 ÷ 2 = 5 余り 0
5 ÷ 2 = 2 余り 1
2 ÷ 2 = 1 余り 0
1 ÷ 2 = 0 余り 1
余りを下から読む → 101010 (2進) = 42 (10進)
8進数(基数8)
使う数字:0〜7。かつてUnixでファイルパーミッション(chmod 755)に使われた。
2進数 → 8進数 の変換(3ビットずつグループ化):
110 101 010 (2進)
↓ ↓ ↓
6 5 2 (8進) = 652 (8進)
なぜ3ビット = 1桁かというと、2³ = 8 だから。
16進数(基数16)
使う数字:0〜9 と A〜F。0x プレフィックスで表記。
対応表:
10進 │ 16進 │ 4ビット2進
─────┼─────┼───────────
0 │ 0 │ 0000
1 │ 1 │ 0001
2 │ 2 │ 0010
3 │ 3 │ 0011
4 │ 4 │ 0100
5 │ 5 │ 0101
6 │ 6 │ 0110
7 │ 7 │ 0111
8 │ 8 │ 1000
9 │ 9 │ 1001
10 │ A │ 1010
11 │ B │ 1011
12 │ C │ 1100
13 │ D │ 1101
14 │ E │ 1110
15 │ F │ 1111
なぜコンピュータは16進数を好むか
1バイト = 8ビット = 16進数2桁でぴったり表せる
8ビット 2進数: 1010 1110
↓ 4ビットずつ分割
A E
= 0xAE
メリット:
・2進数より短く書ける(8文字 → 2文字)
・2進数との変換が暗算で一瞬
・メモリダンプ・アドレス表記に標準
・色コード(#FF5733)、MACアドレス(00:1A:2B:3C:4D:5E)など
バイト(Byte)
なぜ8ビット = 1バイトなのか。
歴史的経緯:
1950〜60年代、コンピュータは様々なバイトサイズを使用
(6ビット・7ビット・8ビットなど)
IBMが1960年代に8ビットを標準化(System/360)
8ビット = 256通り(0〜255)の利点:
・ASCII(7ビット)を格納できる
・16進数2桁でぴったり表せる
・2の累乗ビット(4ビットの倍数)で回路設計が簡単
バイトで表せる範囲:
符号なし:0 〜 255
符号あり(2の補数):-128 〜 127
ASCII:英数字の7ビット符号化
American Standard Code for Information Interchange(1963年制定)。
主要なASCIIコード:
32 (0x20) = スペース
48 (0x30) = '0' ← 数字は48〜57
65 (0x41) = 'A' ← 大文字は65〜90
97 (0x61) = 'a' ← 小文字は97〜122
10 (0x0A) = 改行(LF)
13 (0x0D) = 復帰(CR)
設計の巧みさ:
'A'(65) と 'a'(97) の差 = 32 = 0b00100000
→ ビット5を反転するだけで大文字⇔小文字変換できる
'0'(48) = 0b00110000
'9'(57) = 0b00111001
→ 数字文字から下4ビットを取り出すと数値になる
'5'(53) & 0x0F = 5
Unicode:世界のすべての文字を
ASCII は英語のみ。日本語・中国語・アラビア語・絵文字には対応できない。
Unicodeの設計:
コードポイント(番号)で文字を識別
U+0041 = 'A'(Latin Capital Letter A)
U+3042 = 'あ'(Hiragana Letter A)
U+1F600 = '😀'(Grinning Face)
現在のUnicode:
1,114,112 個のコードポイント(U+0000 〜 U+10FFFF)
うち約15万文字が割り当て済み(2024年時点)
エンコーディング方式:
UTF-32:すべて4バイト固定。シンプルだがファイルが大きい
UTF-16:基本面は2バイト、補助面は4バイト
UTF-8 :可変長(1〜4バイト)。ASCIIと後方互換
UTF-8:可変長エンコーディングの設計
本書第2版で5ページ追加された重要トピック。
UTF-8のエンコーディングルール:
コードポイントの範囲 バイト数 ビットパターン
─────────────────────────────────────────────────
U+0000 〜 U+007F 1バイト 0xxxxxxx
U+0080 〜 U+07FF 2バイト 110xxxxx 10xxxxxx
U+0800 〜 U+FFFF 3バイト 1110xxxx 10xxxxxx 10xxxxxx
U+10000 〜 U+10FFFF 4バイト 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
例:'あ'(U+3042)を UTF-8 にエンコード
U+3042 = 0011 0000 0100 0010 (16ビット)
U+0800〜U+FFFFの範囲 → 3バイト形式
1110xxxx 10xxxxxx 10xxxxxx に当てはめる:
1110[0011] 10[000001] 10[000010]
= 0xE3 0x81 0x82
UTF-8 の設計の巧みさ
1. ASCIIとの互換性
U+0000〜U+007F は従来のASCIIバイトと同一
→ 既存のASCIIテキストはそのままUTF-8として有効
2. 自己同期性
先頭バイトは 0xxxxxxx or 11xxxxxx
継続バイトは 10xxxxxx のみ
→ ストリームの途中から読み始めても文字境界を発見できる
3. バイト順非依存
UTF-8 はバイト単位のエンコーディングなのでエンディアン問題なし
(UTF-16/32 はBOMが必要な場合がある)
変換チートシート
2進 → 10進:各桁に2の累乗をかけて合計
1011(2) = 8+0+2+1 = 11(10)
10進 → 2進:繰り返し2で割り、余りを逆順に並べる
11 → 5余1 → 2余1 → 1余0 → 0余1 → 1011(2)
2進 → 16進:4ビットずつグループ化
1010 1111(2) = A F(16) = 0xAF
16進 → 2進:1桁を4ビットに展開
0x3C = 0011 1100(2)
16進 → 10進:
0xFF = 15×16 + 15 = 255
0x100 = 256
よく使う値を暗記:
0xFF = 255 = 11111111(2)(8ビット最大)
0x80 = 128 = 10000000(2)(8ビット最上位ビット)
0x7F = 127(符号付き8ビットの最大値)
0x0F = 15 = 00001111(2)(下位4ビットのマスク) - 1. 📖CODE:コンピュータのからくり — シリーズ概要
- 2. 📡信号とコード:点字・モールス・情報伝達の原理
- 3. ⚡電気とリレー:懐中電灯から論理ゲートへ
- 4. 🔢数の体系:2進数・16進数・ASCIIからUnicodeへ
- 5. ➕算術回路:加算器・2の補数・減算の実装
- 6. 💾記憶と時計:フリップフロップ・クロック・RAM
- 7. 🖥️CPUの構造:ALU・レジスタ・バス・制御信号
- 8. 🖥️OSとプログラミング:機械語から高水準言語まで
出典: https://www.amazon.co.jp/dp/4296080245