2進数・8進数・10進数・16進数の相互変換についてまとめてみた

### 2進数や8進数などから10進数に変換する
***
■ 2進数の「1101」を10進数に変換する

```math
1\times(2^3) + 1\times(2^2) + 0\times(2^1) + 1\times(2^0) = 13
```

Pythonで実行する場合は  

```py3
>>> int('1101', 2)
13
```

■ 8進数の「700」を10進数に変換する

```math
7\times(8^2) + 0\times(8^1) + 0\times(8^0) = 448
```

Pythonで実行する場合は  

```py3
>>> int('700', 8)
448
```

■ 16進数の「FE」を10進数に変換する

```math
15\times(16^1) + 14\times(16^0) = 254
```

Pythonで実行する場合は

```py3
>>> int('FE', 16)
254
```

### 2進数や8進数などから10進数に変換する（小数の場合）
***
※Pythonで実行する場合は自前で実装する必要がある（参考記事を参照）

■ 2進数の「0.011」を10進数に変換する

```math
0\times(2^{-1}) + 1\times(2^{-2}) + 1\times(2^{-3}) = 0.375
```

■ 8進数の「0.603」を10進数に変換する

```math
6\times(8^{-1}) + 0\times(8^{-2}) + 3\times(8^{-3}) = 0.755859375
```

■ 16進数の「0.A01」を10進数に変換する

```math
10\times(16^{-1}) + 0\times(16^{-2}) + 1\times(16^{-3}) = 0.62524414062
```

### 10進数を2進数や8進数に変換する
***
■ 10進数の「23」を2進数に変換する

2で割ると右にシフトすることを利用する。

```math
23\div2 = 11 \quad余り\quad1\\
11\div2 = 5 \quad余り\quad1\\
5\div2 = 2 \quad余り\quad1\\
2\div2 = 1 \quad余り\quad0\\
1\div2 = 0 \quad余り\quad1\\
余りを下から順につなげて10111
```

Pythonで実行する場合は

```py3
>>> bin(23)
'0b10111'
```

■ 10進数の「23」を8進数に変換する

8で割ると右にシフトすることを利用する。

```math
23\div8 = 2 \quad余り\quad7\\
2\div8 = 0 \quad余り\quad2\\
余りを下から順につなげて27
```

Pythonで実行する場合は

```py3
>>> oct(23)
'0o27'
```

■ 10進数の「23」を16進数に変換する

16で割ると右にシフトすることを利用する。

```math
23\div16 = 1 \quad余り\quad7\\
1\div16 = 0 \quad余り\quad1\\
余りを下から順につなげて17
```

Pythonで実行する場合は

```py3
>>> hex(23)
'0x17'
```

### 10進数を2進数や8進数に変換する（小数の場合）
***
※Pythonで実行する場合は自前で実装する必要がある

■ 10進数の「0.125」を2進数に変換する

2倍すると左にシフトすることを利用する。

```math
0.125\times2 = 0.25 \quad1桁目\quad0\\
0.25\times2 = 0.5 \quad1桁目\quad0\\
0.5\times2 = 1.0 \quad1桁目\quad1\\
1桁目を上から順につなげて0.001
```

■ 10進数の「0.125」を8進数に変換する

8倍すると左にシフトすることを利用する。

```math
0.125\times8 = 1.0 \quad1桁目\quad1\\
1桁目を上から順につなげて0.1
```

■ 10進数の「0.125」を16進数に変換する

16倍すると左にシフトすることを利用する。

```math
0.125\times16 = 2.0 \quad1桁目\quad2\\
1桁目を上から順につなげて0.2
```

### 2進数を8進数や16進数に変換する
***
■ 2進数の「1101101」を8進数に変換する。

3桁ごと（足りない場合はゼロで桁合わせ）に分けて10進数変換し、連結する

```math
001\quad101\quad101\\
0\times(2^2) + 0\times(2^1) + 1\times(2^0) = 1\\
1\times(2^2) + 0\times(2^1) + 1\times(2^0) = 5\\
1\times(2^2) + 0\times(2^1) + 1\times(2^0) = 5\\
連結すると155
```

Pythonで実行する場合は

```py3
>>> format(int('1101101', 2),'o')
'155'
```

■ 2進数の「1101101」を16進数に変換する。

4桁ごと（足りない場合はゼロで桁合わせ）に分けて10進数変換し、連結する

```math
0110\quad1101\\
0\times(2^3) + 1\times(2^2) + 1\times(2^1) + 0\times(2^0) = 6\\
1\times(2^3) + 1\times(2^2) + 0\times(2^1) + 1\times(2^0) = 13\\
連結すると6D
```

Pythonで実行する場合は

```py3
>>> format(int('1101101', 2),'x')
'6d'
```

### 2進数を8進数や16進数に変換する（小数の場合）
***
※Pythonで実行する場合は自前で実装する必要がある

■ 2進数の「0.0110111」を8進数に変換する

3桁ごと（足りない場合はゼロで桁合わせ）に分けて10進数変換し、連結する

```math
011\quad011\quad100\\
0\times(2^{2}) + 1\times(2^{1}) + 1\times(2^{0}) = 3\\
0\times(2^{2}) + 1\times(2^{1}) + 1\times(2^{0}) = 3\\
1\times(2^{2}) + 0\times(2^{1}) + 0\times(2^{0}) = 4\\
連結すると0.334
```

■ 2進数の「0.0110111」を16進数に変換する

4桁ごと（足りない場合はゼロで桁合わせ）に分けて10進数変換し、連結する

```math
0110\quad1110
0\times(2^{3}) + 1\times(2^{2}) + 1\times(2^{1}) + 0\times(2^{0}) = 6\\
1\times(2^{3}) + 1\times(2^{2}) + 1\times(2^{1}) + 0\times(2^{0}) = E\\
連結すると0.6E
```

### 8進数や16進数を2進数にする
***
■ 8進数の「664」を2進数に変換する

それぞれの桁を2進数に変換して連結する

```math
6\div2 = 3 \quad余り\quad0\\
3\div2 = 1 \quad余り\quad1\\
1\div2 = 0 \quad余り\quad1\\
余りを下から順につなげて110\\
6\div2 = 3 \quad余り\quad0\\
3\div2 = 1 \quad余り\quad1\\
1\div2 = 0 \quad余り\quad1\\
余りを下から順につなげて110\\
4\div2 = 2 \quad余り\quad0\\
2\div2 = 1 \quad余り\quad0\\
1\div2 = 0 \quad余り\quad1\\
余りを下から順につなげて100\\
連結すると110110100
```

■ 8進数の「664」を16進数に変換する

2進数に変換してから16進数に変換する

```math
0001\quad1011\quad0100\\
0\times(2^{3}) + 0\times(2^{2}) + 0\times(2^{1}) + 1\times(2^{0}) = 1\\
1\times(2^{3}) + 0\times(2^{2}) + 1\times(2^{1}) + 1\times(2^{0}) = B\\
0\times(2^{3}) + 1\times(2^{2}) + 0\times(2^{1}) + 0\times(2^{0}) = 4\\
連結すると1B4
```

### 8進数や16進数を2進数にする（小数の場合）
***
※Pythonで実行する場合は自前で実装する必要がある

■ 8進数の「0.664」を2進数に変換する

小数以下のそれぞれの桁を2進数に変換して連結する

```math
6\div2 = 3 \quad余り\quad0\\
3\div2 = 1 \quad余り\quad1\\
1\div2 = 0 \quad余り\quad1\\
余りを下から順につなげて110\\
6\div2 = 3 \quad余り\quad0\\
3\div2 = 1 \quad余り\quad1\\
1\div2 = 0 \quad余り\quad1\\
余りを下から順につなげて110\\
4\div2 = 2 \quad余り\quad0\\
2\div2 = 1 \quad余り\quad0\\
1\div2 = 0 \quad余り\quad1\\
余りを下から順につなげて100\\
連結すると0.1101101
```

■ 8進数の「0.664」を16進数に変換する

2進数に変換してから16進数に変換する
```math
1101\quad1010\\
1\times(2^{3}) + 1\times(2^{2}) + 0\times(2^{1}) + 1\times(2^{0}) = D\\
1\times(2^{3}) + 0\times(2^{2}) + 1\times(2^{1}) + 0\times(2^{0}) = A\\
連結すると0.DA
```

### 負の10進数を符号付き2進数や符号付き16進数にする
***
■ 10進数の「-23」を符号付き8bit2進数に変換する

23を2進数に変換した後に、2の補数を求める

```math
23\div2 = 11 \quad余り\quad1\\
11\div2 = 5 \quad余り\quad1\\
5\div2 = 2 \quad余り\quad1\\
2\div2 = 1 \quad余り\quad0\\
1\div2 = 0 \quad余り\quad1\\
余りを下から順につなげて00010111\\
00010111の2の補数は\\
11101000 + 1 = 11101001
```

Pythonで実行する場合は

```py3
>>> '{:08b}'.format(-23 & 0xff)
'11101001'
```

■ 10進数の「-23」を符号付き8bit16進数に変換する

-23を2進数の2の補数に変換した後に、16進数に変換する。

```math
1110\quad1001
1\times(2^{3}) + 1\times(2^{2}) + 1\times(2^{1}) + 0\times(2^{0}) = E\\
1\times(2^{3}) + 0\times(2^{2}) + 0\times(2^{1}) + 1\times(2^{0}) = 9\\
連結するとE9
```

Pythonで実行する場合は

```py3
>>> '{:02x}'.format(-23 & 0xff)
'e9'
```

### 符号付き2進数や符号付き16進数を10進数にする
***

■ 符号付き2進数の「11101001」を10進数に変換する

先頭が1であるため2進数の2の補数を求め、10進数に変換後、マイナスを付ける

```math
11101001の2の補数は\\
00010111\\
1\times(2^{4}) + 0\times(2^{3}) + 1\times(2^{2}) + 1\times(2^{1}) + 1\times(2^{0}) = 23\\
マイナスを付けて-23
```

### 参考になった記事
***
[Python で小数点対応の N 進数から 10 進数に変換するプログラムを書いた](http://d.hatena.ne.jp/r_ikeda/20111030/decimalbin)
[2進数・16進数・論理演算第3日目：シフトと乗算・除算](http://sevendays-study.com/computer-literacy/im-day3.html)
[10 進数から 2 進数への変換](http://www.infonet.co.jp/ueyama/ip/binary/dec2bin.html)
[n 進数の世界 (符号つき数)](http://www.coins.tsukuba.ac.jp/~tomohiro/literacy-13/lecture/n-ary-2.pdf)
[Python | 2の補数のビットパターンを文字列で得る方法](http://pichaelle.hatenablog.jp/entry/2016/12/04/200259)