「n進数」②　桁の重みと基数変換（2進数間）

##n進数における基数
n進数には、その基本となる数を表す基数という考え方があります。
たとえば、2進数なら2、8進数なら8、10進数なら10というように、基数はn進数のnにあたる数字です。

##桁の重み
n進数の基数と桁数の関係性について着目してみます。
その例として、ここでは2進数において1という数字が桁を上げていく様子を見ていきます。

| 2進数　（桁数） | 対応する10進数の値　（2の累乗） |
|:-:|:-:|
|  1　（1）|  1　(2^**0**) |
|  10　（2）|  2　(2^**1**) |
|  100　（3）| 4　(2^**2**)  |
|  1000　（4）| 8　(2^**3**) |
|  10000　（5）|  16　(2^**4**) |
|  100000　（6）|  32　(2^**5**) |
|  1000000　（7）|  64　(2^**6**) |
|  10000000　（8）|  128　(2^**7**) |
|  100000000　（9）|  256　(2^**8**) |

この表を見ると、2進数の値（桁数）が増えて行くのにしたがって、対応する10進数の値も増えていくことが分かります。
しかも、**桁数の増加量**と2進数に対応する10進数の値を2の累乗の形で表したときの**指数部分（2^xのxの数字）の増加量**が相関していることが分かります。

たとえば、2進数の数1000について考えてみると、それに対応する10進数の値は8です。
この8という数は「2の**3**乗」と表すことができます。そして、この指数部分の3は「2進数1000の**桁数4から1を引いた数**」と考えることができます。
同じように、2進数の数100000について考えてみると、それに対応する10進数の値は32です。この32という数は「2の**5**乗」と表すことができます。そして、この指数部分の5は「2進数100000の**桁数6から1を引いた数**」と考えることができます。

だから、この相関関係は上の表のある2進数の桁数（Digits）をDとして、その2進数に対応する10進数の値(Value)をVとすると、
######V＝2^（Dー1）
と表現することができます。

ここで、もう一度上の表に着目すると、この表の2進数は1…という形で始まっていて他の桁の数は全て0になっています。
つまり、この表の2進数の数は各桁数で表現できる最小の数を表しています。

このことを10進数に置き換えて考えてみます。
たとえば、2桁で表すことができる最小の数は10です。そして、3桁で表すことができる最小の数は100です。

| 桁数 | 10進数で表せる最小の数 | 2進数で表せる最小の数 （対応する10進数の値）|
|:-:|:-:|:-:|
|   1|   1|   1（**1**）|
|   2|   10|   10（**2**）|
|   3|   100|   100（**4**）|

私たちが日常的に使っている10進数で101という数を表現する時のことを考えてみます。
すると、当たり前のように感じますが私たちは普段、

（1×**100**）＋（0×**10**）＋（1×**1**）
＝100＋0＋1
＝101

という計算を無意識のうちに行っていることがわかります。
つまり、（各桁の値）×（その桁で表すことができる最小の値）を桁ごとにそれぞれ求めて、
得られた数を足し合わせたものを数として使っているのです。

これと同様に、2進数の101という数を、各桁数で最小の2進数に対応する10進数の値を使って表現すると、

（1×**4**）＋（0×**2**）＋（1×**1**）
＝4＋0＋1
＝5

5という数が求められます。
つまり、2進数101を各桁毎に分解して、その値と各桁数で最小の2進数に対応する10進数を掛け合わせます。そして、得られた値全てを足し合わせるというプロセスを経た数が5になるというわけです。

この式の、各桁数で最小の2進数に対応する10進数の値のことを2進数における**桁の重み**と呼びます。

2進数の桁の重みは　V＝2^（Dー1）　という式で求めましたが、
この式中の2は2進数の2、つまり基数を表しています。
だから、基数（Radix）Rを用いて、V（桁の重み）を
######V=R^(Dー1)
と表すことができます。
この桁の重みを使うことで、2進数や8進数、16進数など様々なn進数を10進数に変換することが簡単になります。
しかも、これまでは2進数の整数を扱ってきましたが、桁の重みを求めるこの式を活用すれば、n進数の小数部分についても10進数に変換することができるようになります。

##基数変換
###2進数から10進数への基数変換
桁の重みを使って、n進数を10進数に変換してみます。
たとえば、2進数の「11010.011」を10進数に基数変換するとします。

| 桁数（D） | 5 | 4 | 3 | 2 | 1 | 　 | -1 | -2 | -3 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| ①2進数の値 | 1 | 1 | 0 | 1 | 0 | . | 0 | 1 | 1 |
|②桁の重み（V)| 16| 8 | 4 | 2 | 1 |  |0.5|0.25|0.125|
|積（①x②）|16|8|0|2|0||0|0.25|0.125|

まず、桁の重み（V）を求める式**V=R^(Dー1)**に基数R＝2と各桁数Dを代入して、各桁の桁の重みを求めます。
そして、2進数の各桁の値と桁の重みとの積を求めます。
得られた各桁の積をすべて足し合わせます。計算式は以下の通りです。

16＋8＋0＋2＋0＋0＋0.25＋0.125
＝26.375

したがって、2進数「11010.011」を10進数に基数変換すると、「26.375」になります。

###10進数から2進数への基数変換（桁の重みを使う方法）
今度は逆に、10進数「26.375」を桁の重みを使って2進数へ基数変換します。
基数変換の方針としては、先ほどの2進数から10進数への基数変換とは逆の
プロセスとなります。

10進数「26.375」は、「2進数の各桁の重み」と「2進数の各桁の値」の積を全て足し合わせて求められたものです。
そして、「2進数の桁の重み」については計算式 **V=R^(Dー1)** で求めることが出来ます。

これらを元に「2進数の各桁の値」を求める方法は以下の通りです。
まず、10進数「26.375」をその数自身を超えない最大の「2進数の各桁の重み」で除算し、その時の商と余りを求めます。
そして次に、その余りを1回目の1つ下の「2進数の各桁の重み」で除算して商と余りを求めます。
10進数の余りがなくなり、それ以上除算できなくなるまでこの作業を繰り返します。

このようにして、10進数の値を「2進数の各桁の重み」で除算した時の商を求めれば良いということになります。

| 桁数（D）    | 5    |    4 |   3 |   2 |   1 ||  -1 | -2 |  -3 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|①10進数の値 |26.375|10.375|2.375|2.375|0.375||0.375|0.375|0.125|
|②桁の重み（V)| 16   |    8 |   4 |   2 | 1   ||0.5  |0.25|0.125|
|①÷②の商   |**1**|**1**|**0**|**1**|**0**||**0**|**1**|**1**|
|①÷②の余り  |10.375| 2.375|2.375|0.375|0.375||0.375|0.125|    0|

この表における「①÷②の商」の部分が基数変換によって求められた2進数各桁の値になります。
小数点を正しい位置に置くと、2進数「11010.011」となります。

|桁数|5|4|3|2|1||-1|-2|-3|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|2進数|1|1|0|1|0|.|0|1|1|

###10進数からn進数への基数変換（割り算と掛け算を使う方法）
10進数から2進数への基数変換するためのもう1つの方法があります。
これは、「**整数部分を基数で除算**」し、「**小数部分を基数で乗算**」することによって基数変換するというものです。

たとえば、10進数「26.375」を2進数に基数変換するとします。
その場合、まず整数部分「26」と小数部分「0.375」に分けます。

|整数部分| 小数部分 |
|:-:|:-:|
|26|0.375|
####①整数部分の基数変換
次に、分けられた整数部分「26」を基数2で除算していきます。
その際、除算で生じた商については、その値が0になるまで繰り返し基数で除算を繰り返し、その度ごとに出た余りはそのまま残しておきます。

|①整数部分(商)|26 |13 |6  |3  |1  |0  |   
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|②基数|   2|   2|   2|   2|   2|   2|   |
|①÷②の商|   13|   6|   3|   1|   0|   |   |
|①÷②の余り|   0|   1|   0|   1|   1|   |   |
|↗︎を右から左に並べ替え|   1|   1|   0|   1|   0|   |   |

ここで、各回の除算で生じた余りについて着目します。
除算で得られた余りをそのまま左から右に並べると、「01011」という値になります。
今度は、この値を右から左に並べ直すと、「11010」という値になります。
この「11010」という値が10進数「26」を2進数へ基数変換したものになります。

#####(A) 10進数「26」を2進数へ基数変換すると「11010」になる。

####②小数部分の基数変換
小数部分「0.375」は基数2で乗算することで基数変換を行います。
まず、小数部分を基数2で乗算することによって得られた値については、そのまま残します。
次に、得られた値の整数部分を無視して小数部分だけを取り出し、さらに基数2で乗算します。
この作業を、乗算によって得られた値の小数部分が0になるまで繰り返します。

|①小数部分|0.375|0.75|0.5|
|:-:|:-:|:-:|:-:|
|②基数|2|2|2|
|①x②の値|0.75|1.5|1.0|
|①x②の値の整数部分|0|1|1|
|①x②の値の小数部分|0.75|0.5|0|

ここで、各回の乗算で得られた値の整数部分について着目します。
この値をそのまま左から右に並べると「011」という値になります。
この「011」という値が10進数「0.375」を2進数へ基数変換した時の**小数部分（小数点より下）**の値になります。
小数部分について、確かに、基数変換した値をそのまま「0.11」としたいところですが、これは誤りになります。
この点に注意して、10進数「0.375」を2進数へ基数変換すると、「0.011」となります。

#####(B) 10進数「0.375」を2進数へ基数変換すると「0.011」になる。
#####したがって、（A）・（B）より小数点の位置に注意して2進数の値を組み合わせると、
#####10進数「26.375」を2進数に基数変換した時の値は「11010.011」になる。

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

##学習してみて
今回の学習範囲は、「n進数とは何か」というテーマに直結するものだったと思います。
日常生活で当たり前のように使っている10進数をどうやって言葉で説明すればいいのかとても苦労しました。
しかも、基本情報技術者の勉強以外ではほとんど触れた事のないの2進数を理解した上で、その基数変換を説明するというのは更なる難関でした。（自分の理解力・文章力が足りないだけかもしれませんが…）
数学的な内容まで踏み込んで学習したわけではありませんので、正確に表現できなかった部分や誤り等が発見されるかもしれません。ご容赦ください。

しかし、私はこのような形で自分が学習したことを自分の言葉で表現することが学習内容への理解を深めることへの一歩ではないかと考えています。
参考書を読んで理解したつもりになることを卒業し、自分の身になる学習を継続するためにも今後も少しずつ積み重ねていきたいと思っています。