1. 数の表現

1.1. 10進法(10進表現)

ふだん私たちが使っている数の表現です。1つの桁に 0〜9 の10種類の記号を用います。各桁の値は基数(base、radix)の冪に対応します。

\[1984_{(10)} = \mathbf{1} \times 10^3 + \mathbf{9} \times 10^2 + \mathbf{8} \times 10^1 + \mathbf{4} \times 10^0\]
表 1. 10進表現 1984(10) の桁と重み

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種類の記号のみを用います。

\[1010_{(2)} = \mathbf{1} \times 2^3 + \mathbf{0} \times 2^2 + \mathbf{1} \times 2^1 + \mathbf{0} \times 2^0 = 8 + 2 = 10\]
表 2. 2進表現 1010(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)といいます。

表 3. 基数の異なる数の対応表
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\))

例
\[1011\ 1001_{(2)} = \mathrm{B9}_{(16)}\]

2. 基数変換

2.1. 2進表現から10進表現へ

2.1.1. 整数部の変換:重みを使う方法

各桁の値と桁の重み(2のべき乗)の積の和として求めます。

表 4. 例:110101(2) → 10進表現

1

1

0

1

0

1

\(2^5\)

\(2^4\)

\(2^3\)

\(2^2\)

\(2^1\)

\(2^0\)

32

16

8

4

2

1

\[32 + 16 + 4 + 1 = 53\]

よって \(110101_{(2)} = 53_{(10)}\)

2.1.2. 整数部の変換:Horner法

上位桁から「基数の2を掛けて次の桁を足す」操作を繰り返します。

\[110101_{(2)} = ((((1 \times 2 + 1) \times 2 + 0) \times 2 + 1) \times 2 + 0) \times 2 + 1 = 53\]
表 7. 例:110101(2) → 53(10)(Horner法)
表 5. 2進
 操作

計

 1×2+1

3

 3×2+0

6

 6×2+1

13

 13×2+0

26

 26×2+1

53

表 6. 10進との対応
 操作

計

 5×10+3

53

10進表現の場合も同様に「上位桁から基数の10を掛けて次の桁を足す」ことで元の値が得られることがわかります。

2.1.3. 小数部の変換:重みを使う方法

小数点以下の各桁の重みは \(2^{-1},\, 2^{-2},\, 2^{-3},\, \ldots\) となります。

表 8. 例:0.1011(2) → 10進表現

.1

0

1

1

\(2^{-1}\)

\(2^{-2}\)

\(2^{-3}\)

\(2^{-4}\)

0.5

0.25

0.125

0.0625

\[0.5 + 0.125 + 0.0625 = 0.6875\]

よって \(0.1011_{(2)} = 0.6875_{(10)}\)

2.1.4. 小数部の変換:Horner法(逆方向)

下位桁から「基数の2で割って次の桁(上位側)を足す」操作を繰り返します。整数部のHorner法と方向が逆になります。

表 11. 例:0.1011(2) → 0.6875(10)(Horner法)
表 9. 2進(下位桁から)
 操作

計

 1÷2+1

1.5

 1.5÷2+0

0.75

 0.75÷2+1

1.375

 1.375÷2

0.6875

表 10. 10進との対応
 操作

計

 5÷10+7

7.5

 7.5÷10+8

8.75

 8.75÷10+6

6.875

 6.875÷10

0.6875

2進表現から10進表現への変換は、章末の練習問題の問題1・問題2で練習できます。

2.2. 10進表現から2進表現へ

2.2.1. 整数部の変換:2の冪による分解法

変換する数を、それ以下で最大の2の冪から順に「詰めて」いきます。使った2の冪に対応するビットを1とし、使わなかったビットを0とします。

例:53(10) → 2進表現

53 以下で最大の2の冪は \(2^5 = 32\)。大きい順に順次差し引きます: \(53 - 32 = 21 \;\to\; 21 - 16 = 5 \;\to\; 5 - 4 = 1 \;\to\; 1 - 1 = 0\)

表 12. 53 の2の冪への分解

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つずつ求めていく手順として理解できます。

表 15. 例:53(10) → 110101(2)(繰り返し除算法)
表 13. 10進の割り算
 10進

余り

 53÷2 = 26

1

 26÷2 = 13

0

 13÷2 = 6

1

  6÷2 = 3

0

  3÷2 = 1

1

  1÷2 = 0

1

表 14. 2進での意味
 2進

余り

 110101÷10 = 11010

1

  11010÷10 = 1101

0

   1101÷10 = 110

1

    110÷10 = 11

0

     11÷10 = 1

1

      1÷10 = 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位が整数部に出てくるのと同じしくみです。

表 16. 繰り返し乗算による変換 0.671875(10) → 0.101011(2)

計算

整数部

 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)。

  1. 小数点を基準に、整数部は右から左へ、小数部は左から右へ、4ビットずつ区切る

  2. 4ビットに足りない端には0を補う(整数部は左端に、小数部は右端に補う。値は変わらない)

  3. 各4ビットを、表 3を使って16進表現の1桁(0〜9、A〜F)に読み替える

1011110は0101 1110で5E、11010111.011は1101 0111.0110でD7.6
図 1. 2進表現と16進表現の変換:小数点から4ビットずつ区切る

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. 練習問題

基本の変換から順に並べています。解答は、自分で解いてから開いてください。

問題1: 2進表現から10進表現へ(整数)

\(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\) であることに注意しましょう。

問題2: 2進表現から10進表現へ(小数を含む)

\(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\) ではありません。

問題3: 2進表現から16進表現へ

次の2進表現を16進表現に変換せよ。

  1. \(1011110_{(2)}\)

  2. \(11010111.011_{(2)}\)

解答
  1. \(\mathrm{5E}_{(16)}\)。右から4ビットずつ区切ると 101 1110。左端に0を補って 0101 1110 → 5、E です。

  2. \(\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の答えと一致することを確かめられます。

問題4: 10進表現から2進表現・16進表現へ(整数)

次の10進表現を、2進表現と16進表現に変換せよ。

  1. \(183_{(10)}\)

  2. \(137_{(10)}\)

解答
  1. \(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。

  2. \(10001001_{(2)}\)、\(89_{(16)}\)。\(137=128+8+1\) です。1000 1001 と区切って 8、9。16進表現の「89」を10進の89と読み違えないように、基数を必ず書きましょう。

16進表現は、10進表現を16で繰り返し割っても求められます(183 ÷ 16 = 11 余り 7 → B7)。

問題5: 10進表現から2進表現・16進表現へ(小数)

次の10進表現を、2進表現と16進表現に変換せよ。

  1. \(0.90625_{(10)}\)

  2. \(0.1_{(10)}\)

解答
  1. \(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 です。

  2. \(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章の「表現誤差」につながります。

問題6: 基数の性質を考える
  1. 2進表現で8桁(8ビット)の数は、10進表現で0からいくつまでを表せるか。また、16進表現では何桁になるか。

  2. ある数の2進表現の右端に0を1つ付け加えると、値はどうなるか。10進表現の場合と比べて説明せよ。

解答
  1. 0から \(2^8-1=255\) まで。16進表現では2桁(\(00_{(16)}\) 〜 \(\mathrm{FF}_{(16)}\))です。4ビットで16進表現の1桁になるので、8ビットはちょうど2桁です。

  2. 値は2倍になります。すべての桁が1つ上の位(重みが2倍の位)へずれるからです。10進表現で右端に0を付けると10倍になるのと同じしくみで、一般に \(n\) 進表現では \(n\) 倍になります。


← 目次へ戻る

© 久保山哲二 「コンピューター科学概論」講義資料 — CC BY-NC-SA 4.0 (表示 - 非営利 - 継承)で公開しています。