1. 数の表現
1.1. 10進法(10進表現)
ふだん私たちが使っている数の表現です。1つの桁に 0〜9 の10種類の記号を用います。各桁の値は基数(base、radix)の冪に対応します。
1 |
9 |
8 |
4 |
|---|---|---|---|
1000 |
100 |
10 |
1 |
-
表現と意味は別モノ:1984(10) は「10進表現された数 1984」を表す
-
この資料では、基数を右下の括弧で示して 1984(10)、1010(2) のように書きます(本文の第3章と同じ表記です)。基数が明らかなときは省略します。
-
10進表現 \(n\) 桁で表現できる数の範囲:\(0 \;\sim\; 10^n - 1\)(例:3桁では 0〜999)
1.2. 2進法(2進表現)
コンピューター等で使われている数の表現です。スイッチの on/off に対応し、1つの桁に 0 と 1 の2種類の記号のみを用います。
1 |
0 |
1 |
0 |
|---|---|---|---|
8 |
4 |
2 |
1 |
-
2進表現 \(n\) 桁で表現できる数の範囲:\(0 \;\sim\; 2^n - 1\)(例:3桁では 0〜7)
-
2進表現の1桁 = bit(binary digit)
1.3. n進表現
一般に1つの桁に n 種類の記号を用いる数の表現を n進法といい、n を基数(base、radix)といいます。
| 10進 | 2進 | 3進 | 4進 | 8進 | 16進 |
|---|---|---|---|---|---|
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
2 |
10 |
2 |
2 |
2 |
2 |
3 |
11 |
10 |
3 |
3 |
3 |
4 |
100 |
11 |
10 |
4 |
4 |
5 |
101 |
12 |
11 |
5 |
5 |
6 |
110 |
20 |
12 |
6 |
6 |
7 |
111 |
21 |
13 |
7 |
7 |
8 |
1000 |
22 |
20 |
10 |
8 |
9 |
1001 |
100 |
21 |
11 |
9 |
10 |
1010 |
101 |
22 |
12 |
A |
11 |
1011 |
102 |
23 |
13 |
B |
12 |
1100 |
110 |
30 |
14 |
C |
13 |
1101 |
111 |
31 |
15 |
D |
14 |
1110 |
112 |
32 |
16 |
E |
15 |
1111 |
120 |
33 |
17 |
F |
16 |
10000 |
121 |
100 |
20 |
10 |
16進表現では1桁に16種類の記号が必要なため、0〜9 に加えて A〜F の文字を用います(A=10, B=11, …, F=15)。
2進表現のコンパクトな表現として 16進表現がよく使われます:
-
16進表現の1桁 = 4進表現の2桁 = 2進表現の4桁(\(2^4 = 16\))
-
8進表現の1桁 = 2進表現の3桁(\(2^3 = 8\))
2. 基数変換
2.1. 2進表現から10進表現へ
2.1.1. 整数部の変換:重みを使う方法
各桁の値と桁の重み(2のべき乗)の積の和として求めます。
1 |
1 |
0 |
1 |
0 |
1 |
|---|---|---|---|---|---|
\(2^5\) |
\(2^4\) |
\(2^3\) |
\(2^2\) |
\(2^1\) |
\(2^0\) |
32 |
16 |
8 |
4 |
2 |
1 |
よって \(110101_{(2)} = 53_{(10)}\)
2.1.2. 整数部の変換:Horner法
上位桁から「基数の2を掛けて次の桁を足す」操作を繰り返します。
|
|
10進表現の場合も同様に「上位桁から基数の10を掛けて次の桁を足す」ことで元の値が得られることがわかります。
2.1.3. 小数部の変換:重みを使う方法
小数点以下の各桁の重みは \(2^{-1},\, 2^{-2},\, 2^{-3},\, \ldots\) となります。
.1 |
0 |
1 |
1 |
|---|---|---|---|
\(2^{-1}\) |
\(2^{-2}\) |
\(2^{-3}\) |
\(2^{-4}\) |
0.5 |
0.25 |
0.125 |
0.0625 |
よって \(0.1011_{(2)} = 0.6875_{(10)}\)
2.1.4. 小数部の変換:Horner法(逆方向)
下位桁から「基数の2で割って次の桁(上位側)を足す」操作を繰り返します。整数部のHorner法と方向が逆になります。
|
|
2進表現から10進表現への変換は、章末の練習問題の問題1・問題2で練習できます。
2.2. 10進表現から2進表現へ
2.2.1. 整数部の変換:2の冪による分解法
変換する数を、それ以下で最大の2の冪から順に「詰めて」いきます。使った2の冪に対応するビットを1とし、使わなかったビットを0とします。
53 以下で最大の2の冪は \(2^5 = 32\)。大きい順に順次差し引きます: \(53 - 32 = 21 \;\to\; 21 - 16 = 5 \;\to\; 5 - 4 = 1 \;\to\; 1 - 1 = 0\)
10進 |
2進 |
|
|---|---|---|
32 |
100000 |
= \(2^5\) |
16 |
010000 |
= \(2^4\) |
4 |
000100 |
= \(2^2\) |
1 |
000001 |
= \(2^0\) |
53 |
110101 |
よって \(53_{(10)} = 110101_{(2)}\)
2.2.2. 整数部の変換:繰り返し除算法
基数の2で0になるまで繰り返し割り、余りを下から順に並べます。
この方法は、整数の各桁を1つずつ求めていく手順として理解できます。
|
|
余りを下から上の順に並べると:1 1 0 1 0 1 → \(110101_{(2)}\)
整数部のHorner法(2→10方向)が「上位桁から掛けて足す」なのに対し、この除算法は「下位桁から1桁ずつ取り出す」逆の手順に対応しています。
2.2.3. 小数部の変換:繰り返し乗算法
小数部に2を掛け、整数部(0 または 1)を記録し、小数部が0になるまで繰り返します。整数部を上から順に並べます。 小数部がいつまでも0にならない場合は、必要な桁数で打ち切ります。
2を掛けると、2進表現の小数点が1桁右にずれ、小数第1位の桁が整数部に出てきます。10進法で10を掛けると小数第1位が整数部に出てくるのと同じしくみです。
計算 |
整数部 |
|---|---|
0.671875 × 2 = 1.34375 |
1 |
0.34375 × 2 = 0.6875 |
0 |
0.6875 × 2 = 1.375 |
1 |
0.375 × 2 = 0.75 |
0 |
0.75 × 2 = 1.5 |
1 |
0.5 × 2 = 1.0 |
1 |
整数部を上から順に並べると:1 0 1 0 1 1 → \(0.101011_{(2)}\)
|
10進の小数がすべて有限桁の2進小数になるわけではありません。\(0.1_{(10)}\) は2進表現すると無限循環小数になります。これは、コンピューター上での浮動小数点演算における「表現誤差」の原因の1つです(第3章 コンピューター内部の数の表現 で扱います)。 |
2.3. 2進表現と16進表現の相互変換
\(2^4=16\) なので、2進表現の4桁が16進表現の1桁にちょうど対応します。そのため、2進表現と16進表現の変換は、10進表現を経由せずに「4ビットずつ区切って読み替える」だけでできます(図 1)。
-
小数点を基準に、整数部は右から左へ、小数部は左から右へ、4ビットずつ区切る
-
4ビットに足りない端には0を補う(整数部は左端に、小数部は右端に補う。値は変わらない)
-
各4ビットを、表 3を使って16進表現の1桁(0〜9、A〜F)に読み替える
16進表現から2進表現へ戻すときは逆に、16進表現の各桁を4ビットの2進表現に置き換えます。たとえば \(\mathrm{B9}_{(16)}\) は、B → 1011、9 → 1001 なので 1011 1001 です。
小数部の0を補う位置を間違えやすいので注意しましょう。\(0.011_{(2)}\) の右端に0を補った 0110 は 6 ですが、左端に補って 0011 とすると 3 になり、誤りです。小数部の右端の0は値を変えませんが、左端(小数点のすぐ右)に0を入れると値が変わってしまいます。
8進表現の場合も同じ考え方で、3ビットずつ区切ります。
3. 練習問題
基本の変換から順に並べています。解答は、自分で解いてから開いてください。
\(1011110_{(2)}\) を10進表現に変換せよ。
解答
\(94_{(10)}\)。
重みを使うと \(64+16+8+4+2=94\) です。Horner法なら、上位桁から \(1\to 2\to 5\to 11\to 23\to 47\to 94\) と「2倍して次の桁を足す」を繰り返します。桁の重みは右端が \(2^0=1\) であることに注意しましょう。
\(11010111.011_{(2)}\) を10進表現に変換せよ。
解答
\(215.375_{(10)}\)。
整数部は \(128+64+16+4+2+1=215\)、小数部は \(0.011_{(2)}=0.25+0.125=0.375\) です。小数第1位の重みは \(2^{-1}=0.5\) で、\(0.1\) ではありません。
次の2進表現を16進表現に変換せよ。
-
\(1011110_{(2)}\)
-
\(11010111.011_{(2)}\)
解答
-
\(\mathrm{5E}_{(16)}\)。右から4ビットずつ区切ると
101 1110。左端に0を補って0101 1110→ 5、E です。 -
\(\mathrm{D7.6}_{(16)}\)。小数点から区切って
1101 0111 . 011。小数部は右端に0を補って0110→ 6 です。
(b)で小数部を 0011 → 3 としてしまうのが典型的な誤りです(図 1)。検算として、\(\mathrm{D7.6}_{(16)}=13\times 16+7+\frac{6}{16}=215.375\) が問題2の答えと一致することを確かめられます。
次の10進表現を、2進表現と16進表現に変換せよ。
-
\(183_{(10)}\)
-
\(137_{(10)}\)
解答
-
\(10110111_{(2)}\)、\(\mathrm{B7}_{(16)}\)。2で繰り返し割ると、余りは下から順に 1, 0, 1, 1, 0, 1, 1, 1 です(\(183=128+32+16+4+2+1\))。
1011 0111と区切って B、7。 -
\(10001001_{(2)}\)、\(89_{(16)}\)。\(137=128+8+1\) です。
1000 1001と区切って 8、9。16進表現の「89」を10進の89と読み違えないように、基数を必ず書きましょう。
16進表現は、10進表現を16で繰り返し割っても求められます(183 ÷ 16 = 11 余り 7 → B7)。
次の10進表現を、2進表現と16進表現に変換せよ。
-
\(0.90625_{(10)}\)
-
\(0.1_{(10)}\)
解答
-
\(0.11101_{(2)}\)、\(0.\mathrm{E8}_{(16)}\)。2を掛けていくと、整数部に 1, 1, 1, 0, 1 が出て、小数部が0になります(0.90625 → 1.8125 → 1.625 → 1.25 → 0.5 → 1.0)。16進表現へは、小数点から右へ
1110 1000と区切り(右端に0を3つ補う)、E、8 です。 -
\(0.000110011001100\cdots_{(2)}\)(
0011の繰り返し)、\(0.1999\cdots_{(16)}\)(9の繰り返し)。2を掛けていくと 0.2 → 0.4 → 0.8 → 1.6 → 1.2 → 0.4 → … と、0.2以降が循環するので、有限桁では表せません。4ビットずつ区切ると0001 1001 1001 …なので、16進表現では 1 の後に 9 が続きます。
(b)の結果は、10進表現では短い小数が2進表現では循環小数になる例です。第3章の「表現誤差」につながります。
-
2進表現で8桁(8ビット)の数は、10進表現で0からいくつまでを表せるか。また、16進表現では何桁になるか。
-
ある数の2進表現の右端に0を1つ付け加えると、値はどうなるか。10進表現の場合と比べて説明せよ。
解答
-
0から \(2^8-1=255\) まで。16進表現では2桁(\(00_{(16)}\) 〜 \(\mathrm{FF}_{(16)}\))です。4ビットで16進表現の1桁になるので、8ビットはちょうど2桁です。
-
値は2倍になります。すべての桁が1つ上の位(重みが2倍の位)へずれるからです。10進表現で右端に0を付けると10倍になるのと同じしくみで、一般に \(n\) 進表現では \(n\) 倍になります。