「n進数」③　基数変換（2進数と8進数・16進数間）　

##2進数と8進数・16進数の関係性
####2進数と8進数
8進数は1つの桁で、0〜7までの8つの数を表現します。
この範囲に相当する2進数の値を比較してみると、以下のようになります。

| 10進数 || 2進数 | 8進数 |
|:-:|:-:|:-:|:-:|
|  0 || 0  | 0  |
|  1 || 1  | 1  |
|  2 || 10  | 2  |
|  3 || 11  | 3  |
|  4 || 100  | 4  |
|  5 || 101  | 5  |
|  6 || 110  | 6  |
|  7 || 111  | 7  |

この表を見ると、8進数が1桁で0〜7の値を表現できるのに対して、2進数は同じ範囲を表現するのに最大で3桁使わなければならないということがわかります。
言い換えると、**8進数1桁で2進数3桁分の範囲の値を表現できる**のです。

####2進数と16進数
同様に、今度は16進数について考えてみます。
16進数は1つの桁で、0〜Fまでの16個の数を表現します。
この範囲に相当する2進数の値を比較してみると、以下のようになります。

| 10進数 || 2進数 | 16進数 |
|:-:|:-:|:-:|:-:|
|  0 || 0  | 0  |
|  1 || 1  | 1  |
|  2 || 10  | 2  |
|  3 || 11  | 3  |
|  4 || 100  | 4  |
|  5 || 101  | 5  |
|  6 || 110  | 6  |
|  7 || 111  | 7  |
|  8 || 1000  | 8  |
|  9 || 1001  | 9  |
|  10 || 1010  | A  |
|  11 || 1011  | B  |
|  12 || 1100  | C  |
|  13 || 1101  | D  |
|  14 || 1110  | E  |
|  15 || 1111  | F  |

この表を見ると、16進数が1桁で0〜Fの値を表現できるのに対して、2進数は同じ範囲を表現するのに最大で4桁使わなければならないということがわかります。
言い換えると、**16進数1桁で2進数4桁分の範囲の値を表現できる**のです。

##2進数と8進数間の基数変換
###①2進数の値を8進数に基数変換する
「8進数1桁で2進数3桁分の範囲の値を表現できる」という性質を利用して、2進数を8進数に基数変換していきます。

ここでは例として、2進数「10110.1011」を8進数に変換してみます。
まず、「10110.1011」を**小数点の位置**を基準に**3桁ごと**に区切ります。

| 1 | 0 || 1 | 1 | 0 | . | 1 | 0 | 1 |  | 1 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
両端の数について着目すると、2桁あるいは1桁になっていて、3桁の数になっていません。
そこで、両端の数が3桁になるように**0を補います**。

| 0 | 1 | 0 || 1 | 1 | 0 |  | 1 | 0 | 1 |  | 1 | 0 | 0 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
こうして、区切られた2進数3桁の数が8進数1桁に対応するものとなりました。
次に、区切られた数をそれぞれ10進数に基数変換します。
ここでは、2進数の値に桁の重みをかける方法を使っています。

|①2進数| 0 | 1 | 0 || 1 | 1 | 0 | | 1 | 0 | 1 || 1 | 0 | 0 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|②桁の重み| 4 | 2 | 1 || 4 | 2 | 1 |   | 4 | 2 | 1 || 4 | 2 | 1 |
|①x②の積| 0 | 2 | 0 || 4 | 2 | 0 |   | 4 | 0 | 1 || 4 | 0 | 0 |
|↑の値の和|  | **2** |  ||  | **6** |  |   |  | **5** |  ||| **4** |  |
すると、区切られた3桁の2進数が10進数に基数変換され、それぞれ「2」、「6」、「5」、「4」という値が得られました。
今度はこの値を小数点の位置に注意してそのまま組み合わせます。

|**2**|**6**|.|**5**|**4**|
|:-:|:-:|:-:|:-:|:-:|
こうして、2進数の値「10110.1011」が8進数の値「26.54」という値に基数変換されました。

###②8進数の値を2進数に基数変換する
今度は逆に8進数の値「26.54」を2進数に基数変換します。
まず、「26.54」の各桁を1桁ごとに分割します。

|**2**||**6**|.|**5**||**4**|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
次に、分割された各桁それぞれを2進数に基数変換します。
この時のポイントとして、基数変換後の2進数の値を**3桁**で表現することに注意してください。

####（1）8進数「2」を2進数にする

| ①8進数の値（2回目以降は商） | ②基数 | ①÷②の商 | 余り |
|:-:|:-:|:-:|:-:|
| 2  | 2 | 1 | **0** |
| 1  | 2 | 0 | **1** |
得られた余りの値を下から上に並べると、「10」という数になります。
そして、「10」を3桁で表現するために0を加えて、「010」という数になります。
これが8進数「2」を2進数に基数変換した数になります。

| 8進数の値 | 2進数3桁で表した時の値 |
|:-:|:-:|
|  2 | 010  |


####（2）8進数「6」を2進数にする

| ①8進数の値（2回目以降は商） | ②基数 | ①÷②の商 | 余り |
|:-:|:-:|:-:|:-:|
| 6  | 2 | 3 | **0** |
| 3  | 2 | 1 | **1** |
| 1  | 2 | 0 | **1** |
得られた余りの値を下から上に並べると、「110」という数になります。
したがって、これが8進数「2」を2進数に基数変換した数です。

| 8進数の値 | 2進数3桁で表した時の値 |
|:-:|:-:|
|  6 | 110  |

####（3）8進数「5」を2進数にする

| ①8進数の値（2回目以降は商） | ②基数 | ①÷②の商 | 余り |
|:-:|:-:|:-:|:-:|
| 5  | 2 | 2 | **1** |
| 2  | 2 | 1 | **0** |
| 1  | 2 | 0 | **1** |
得られた余りの値を下から上に並べると、「101」という数になります。
したがって、これが8進数「2」を2進数に基数変換した数です。

| 8進数の値 | 2進数3桁で表した時の値 |
|:-:|:-:|
|  5 | 101  |

####（4）8進数「4」を2進数にする

| ①8進数の値（2回目以降は商） | ②基数 | ①÷②の商 | 余り |
|:-:|:-:|:-:|:-:|
| 4  | 2 | 2 | **0** |
| 2  | 2 | 1 | **0** |
| 1  | 2 | 0 | **1** |
得られた余りの値を下から上に並べると、「100」という数になります。
したがって、これが8進数「2」を2進数に基数変換した数です。

| 8進数の値 | 2進数3桁で表した時の値 |
|:-:|:-:|
| 4 | 100  |

（1）〜（4）より、8進数各桁の値を2進数に基数変換することができました。

|**2**||**6**|.|**5**||**4**|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|010||110||101||100|

次に、これらの値を小数点の位置に気をつけてそのままくっつけます。
そして、両端の「0」を削り落とします。

|010|110|.|101|100|
|:-:|:-:|:-:|:-:|:-:|
|10|110|.|101|1|

こうして、8進数「26.54」が2進数「10110.1011」へ基数変換されました。

| 8進数 | 2進数 |
|:-:|:-:|
|26.54|10110.1011|

##2進数と16進数間の基数変換
###①2進数の値を16進数に基数変換する
「16進数1桁で2進数4桁分の範囲の値を表現できる」という性質を利用して、2進数を16進数に基数変換していきます。

ここでは例として、2進数「10110.1011」を16進数に変換してみます。
まず、「10110.1011」を**小数点の位置**を基準に**4桁ごと**に区切ります。

| 1 || 0 | 1 | 1 | 0 | . | 1 | 0 | 1 | 1 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
左端の数について着目すると、1桁になっていて、4桁の数になっていません。
そこで、左端の数が4桁になるように**0を補います**。

| 0 | 0 | 0 | 1 | | 0 | 1 | 1 | 0 |  | 1 | 0 | 1 | 1 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
こうして、区切られた2進数4桁の数が16進数1桁に対応するものとなりました。
次に、区切られた数をそれぞれ10進数に基数変換します。
ここでは、2進数の値に桁の重みをかける方法を使っています。

|①2進数| 0 | 0 | 0 | 1 || 0 | 1 | 1 | 0 || 1 | 0 | 1 | 1 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|②桁の重み| 8 | 4 | 2 | 1 || 8 | 4 | 2 | 1 || 8 | 4 | 2 | 1 |
|①x②の積| 0 | 0 | 0 | 1 || 0 | 4 | 2 | 0 || 8 | 0 | 2 | 1 |
|↑の値の和|  |**1**|  |  |  |  | **6** |  |  |  |  | **11** |

区切られた4桁の2進数がすべて10進数に基数変換され、それぞれ「1」、「6」、「11」という値が得られました。

ここで、基数変換された10進数「11」に注目します。
この「11」という数は、10進数2桁で表現された数です。しかし、16進数ではこの数を「**B**」という1桁の数として表現することができます。
したがって、基数変換された10進数を16進数の表現で置き換えると、それぞれ「1」、「6」、「B」になります。

次に、この値を小数点の位置に注意してそのまま組み合わせます。

|**1**|**6**|.|**B**|
|:-:|:-:|:-:|:-:|:-:|
こうして、2進数の値「10110.1011」が16進数の値「16.B」という値に基数変換されました。

###②16進数の値を2進数に基数変換する
今度は逆に16進数の値「16.B」を2進数に基数変換します。
まず、「16.B」の各桁を1桁ごとに分割します。

|**1**||**6**|.|**B**|
|:-:|:-:|:-:|:-:|:-:|
このとき、「B」という数が16進数の表現のままになっていることに注意してください。
2進数に基数変換しやすくなるように、**「B」を10進数に基数変換**しておきます。
16進数「B」は10進数では「11」になります。
したがって、分割された数は「1」、「6」、「**11**」となります。

|**1**||**6**||**11**|
|:-:|:-:|:-:|:-:|:-:|

次に、分割された各桁それぞれを2進数に基数変換します。
この時のポイントとして、基数変換後の2進数の値を**4桁**で表現することに注意してください。

####（1）16進数「1」を2進数にする

| ①16進数の値 | ②基数 | ①÷②の商 | 余り |
|:-:|:-:|:-:|:-:|
| 1  | 2 | 0 | **1** |

得られた余りの値は「1」という数になります。
そして、「1」を4桁で表現するために0を加えて、「0001」という数になります。
これが16進数「1」を2進数に基数変換した数になります。

| 16進数の値 | 2進数4桁で表した時の値 |
|:-:|:-:|
|  1 | 0001  |

####（2）16進数「6」を2進数にする

| ①16進数の値（2回目以降は商） | ②基数 | ①÷②の商 | 余り |
|:-:|:-:|:-:|:-:|
| 6  | 2 | 3 | **0** |
| 3  | 2 | 1 | **1** |
| 1  | 2 | 0 | **1** |
得られた余りの値を下から上に並べると、「110」という数になります。
そして、「110」を4桁で表現するために0を加えて、「0110」という数になります。
これが16進数「6」を2進数に基数変換した数です。

| 16進数の値 | 2進数4桁で表した時の値 |
|:-:|:-:|
|  6 | 0110  |

####（3）16進数「B」を2進数にする

| ①16進数の値（2回目以降は商） | ②基数 | ①÷②の商 | 余り |
|:-:|:-:|:-:|:-:|
| 11  | 2 | 5 | **1** |
| 5  | 2 | 2 | **1** |
| 2  | 2 | 1 | **0** |
| 1  | 2 | 0 | **1** |
得られた余りの値を下から上に並べると、「1011」という数になります。
これが16進数「11」を2進数に基数変換した数です。

| 16進数の値 | 2進数4桁で表した時の値 |
|:-:|:-:|
|  11 | 1011 |

（1）〜（3）より、16進数各桁の値を2進数に基数変換することができました。

|16進数|**1**||**6**|.|**B**|
|:-:|:-:|:-:|:-:|:-:|:-:|
|2進数|0001||0110||1011|

次に、これらの値を小数点の位置に気をつけてそのままくっつけます。
そして、左端の「0」を削り落とします。

|0001|0110|.|1011|
|:-:|:-:|:-:|:-:|
|1|0110|.|1011|

こうして、16進数「16.B」が2進数「10110.1011」へ基数変換されました。

| 16進数 | 2進数 |
|:-:|:-:|
|16.B|10110.1011|

##参考にさせて頂いた書籍
きたみりゅうじ 『キタミ式イラストIT塾 基本情報技術者平成31/01年』 技術評論社 2019年

##学習してみて
n進数の扱いにも大分慣れてきたように思います。2進数と8進数・16進数間の基数変換では、**その間に10進数の基数変換を経由する**ようなイメージを持っていればやりやすいですね。
基数変換のプロセスでも、パズル問題を解いているような感覚でやっているので個人的に面白かったです。
次回からは2進数の足し算・引き算について学習していこうと思います。