[光-Hikari-のPython]02章-06＜補足＞ Pythonプログラムの基礎（数値の取り扱い）

#[Python]＜補足＞ 02章-06 数値の取り扱い
ここでは数値の取り扱いについて少し掘り下げてみていきたいと思います。
なお、ここの節は実務ではあまり取り扱いすることはなく、<font color=red>＜補足＞ </font>としていますので、本節は飛ばしても構いません。

少し理論的なお話が中心となると思われます。

ただし、**ITパスポート試験や基本情報技術者試験の受験を考えている方は基礎理論で取り扱われる内容ですので、目を通しておきましょう**。

##数値について
「02章-01」で説明しましたが、数値には以下のように分けられます。

- 整数<br>
　　例）10,  -7,  321 など
- 浮動小数点数（実数）<br>
　　例）3.14,  -2.718,  6.02×10<sup>23</sup> など

この中で、「整数」について少し掘り下げてみたいと思います。

##基数（N進数）
我々が普段扱っている数値は**10進数（Decimal number）**となります。
実際に「0」「1」「2」「3」「4」「5」「6」「7」「8」「9」という10種類の数字を使って数値を表現しています。

しかしコンピュータは「0」か「1」の2つしか扱いません。これを**2進数（
Binary number）**と言います。

例えば、10進数の45は、2進数では101101と表記します。

2進数、10進数だけでなく、よく使われるN進数として、8進数（Octal number）、16進数（Hexadecimal）もあります。

##基数の変換
まずは2進数と10進数の変換について述べていきたいと思います。（わかる方は飛ばしても構いません）

####2進数→10進数への変換
先ほどの2進数、101101を変換することを考えてみます。この2進数を以下の表にしてまとめてみました。

| 番号  | 5 | 4 | 3 | 2 | 1 | 0  |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 2進数  | 1  | 0 | 1 | 1 | 0 | 1  |

上記の表を見ると、それぞれの数字に番号を割り当てています。
しかもあえて、右から0, 1, 2, 3, 4, 5と割り当てました。この番号が後から重要になりますので覚えておいてください。

さて、上記の表でそれぞれの桁に**重み**をつけていきます。重みとは、N進数であればN<sup>m</sup>といった、Nに各桁の番号の累乗したものものです。
以下の表にどういうことかをまとめましたので、確認してください。

| 番号  | 5 | 4 | 3 | 2 | 1 | 0  |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 2進数  | 1  | 0 | 1 | 1 | 0 | 1  |
| 重み | 2<sup>5</sup>  | 2<sup>4</sup> | 2<sup>3</sup> | 2<sup>2</sup> | 2<sup>1</sup> | 2<sup>0</sup>  |

そして、これら重みを2進数の各桁と掛け合わせたものを以下のように足していきます。

```math
\begin{align}
&(2^{5}×1)+(2^{4}×0)+(2^{3}×1)+(2^{2}×1)+(2^{1}×0)+(2^{0}×1)\\
&=32　　+　0　+　　8　+　　4　+　　0　+　　1\\
&=45
\end{align}
```

上記のように、10進数を求めることができました。

####10進数→2進数への変換
では反対に10進数から2進数への変換を見ていきます。先ほどの10進数の45を2進数にしてみましょう。

一般的には10進数の数値をN進数のNで割っていき、それぞれの余りを求めていきます。
今回は2進数へ変換なので、以下のように2で割ります。
45を2で割ると商が22となり、1余るので、それを右に書いていきます。

```math
45÷2=22 ・・・1
```

さらに、22を2で割ると商が11となり割り切れますが、この場合、以下のように**0余ると考えて**ください。

```math
22÷2=11 ・・・0
```

これを繰り返していくと以下のようになります。よく、2進数を求めるには割り算のひっ算の逆を描いて計算することが多いです。

<img width="244" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/77d88767-d661-0cd7-cff9-f3db617a860e.png">

最後に右に書かれているあまりの「0」「1」ですが、これを下か順に並べていきます。

<img width="259" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/3ed7d21b-8b92-654a-b2c3-d7bca619e08f.png">

すると、「101101」となり、10進数45の2進数を求めることができました。

####16進数、8進数の取り扱い
前述した通り10進数では「0」「1」「2」「3」「4」「5」「6」「7」「8」「9」という10種類の数字を使って数値を表現しています。

8進数は「0」「1」「2」「3」「4」「5」「6」「7」という8種類の数字を使って数値を表現するのは予測できると思いますが、16進数はどうなるのでしょうか？

「9」の次は「10」「11」「12」「13」「14」「15」と続くのですが、そうすると「15」が本当に「15」なのか、「1」と「5」がくっついているのかわかりません。

そこで、**16進数は以下の表のようにa～fを使って表記**します。

| 2進数 | 8進数 | 10進数 | 16進数 |
|:-:|:-:|:-:|:-:|
|  0000 | 0  | 0  | 0  |
|  0001 | 1  | 1  | 1  |
|  0010 | 2  | 2  | 2  |
| 0011  | 3  | 3  | 3  |
| 0100  | 4  | 4  | 4  |
| 0101  | 5  | 5  | 5  |
| 0110  | 6  | 6  | 6  |
| 0111  | 7  | 7  |  7 |
| 1000  | 10  | 8  |  8 |
| 1001  | 11  | 9  |  9 |
| 1010  | 12  | 10 | <font color=red>a</font>  |
| 1011  | 13  | 11 | <font color=red>b</font>  |
| 1100  | 14  | 12 | <font color=red>c</font>  |
| 1101  | 15  | 13 | <font color=red>d</font>  |
| 1110  | 16  | 14 | <font color=red>e</font>  |
| 1111  | 17  | 15 | <font color=red>f</font>  |

2進数は表記するとどうしても長くなるため、16進数で表現すれば**長さを圧縮でき見やすくなるという利点**があります。

####16進数から10進数への変換
例えば、16進数の「5c2」を10進数で表すことを考えます。これも表を使って考えます。
なお、cは上記の表より12なので、以下のように12で計算します。

| 番号  | 2 | 1 | 0  |
|:-:|:-:|:-:|:-:|
| 16進数  | 5 | c<br>(12) | 2  |
| 重み| 16<sup>2</sup> | 16<sup>1</sup> | 16<sup>0</sup>  |

これを先ほどの2進数の時と同じように重みをかけて足していきます。

```math
\begin{align}
&(16^{2}×5)+(16^{1}×12)+(16^{0}×2)\\
&=1280　　+　192　+　　2　\\
&=1474
\end{align}
```

また、逆に10進数から16進数の変換も、以下のように今度は16で割っていった余りを並べていき求めていきます。

<img width="307" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/89e43e88-cf3c-e647-469b-259a2f63a58b.png">

すると、「5c2」となり、10進数1474の16進数を求めることができました。

8進数の場合も同じように、8で割っていき、その余りを並べていきます。

##そのほかのN進数
今まで、2進数、8進数、10進数、16進数と扱ってきましたが、では、ほかの3進数や5進数などは扱わないのでしょうか？

実は3進数も5進数も存在はしますが、ほとんど使用されることはありません。
求め方は10進数を3で割っていき求めていく方法は変わらないです。

実は2進数は、8進数や16進数と相性が良く、先ほどの表のようにすぐに求めることができます。
前述した通り、2進数ですと表記が長くなるため、16進数を用いて変換して圧縮して見やすくするといったことがよく用いられます。

例えば2進数「00101101」をそのまま16進数に変えたいときは、2進数を4つ区切りで表現し、それを上の表から16進数を求めればすぐに変換可能です。

```math
0010　1101 = 2d
```

##Pythonにおける基数の変換
では、これをPythonを使って変換していきたいと思います。
今回は、**Python Console**を使用して、説明していきます。

先ほどの例の数値を用いて説明します。まずは、2進数、8進数、16進数から10進数への変換を考えます。以下のようにコードを入力してください。
上から、2進数、8進数、16進数の順で10進数に変換しています。

```.py
>>> bin(45)
'0b101101'
>>> oct(45)
'0o55'
>>> hex(1474)
'0x5c2'
```
2進数へは**bin関数**で、8進数へは**oct関数**で、16進数へは**hex関数**で変換できます。
また出力結果について、0b（ゼロ・ビー）はBinary（2進数）を表し、0o（ゼロ・オー）はOctalを表し、0x（ゼロ・エックス）はHexadecimal（16進数）を表します。

では、反対に2進数、8進数、16進数はどのように10進数に変換できるかを見ていきます。
以下のようにコードを入力してください。

```.py
>>> 0b101101
45
>>> 0o55
45
>>> 0x5c2
1474
```

変換したい数値の前にそれぞれ「0b」「0o」「0x」と付与するのみです。

##浮動小数点数について
最後に、補足として浮動小数点数について述べていきます。
例えば、以下の実数

```math
2.718
```
は通常通りの表記となります。

他に、大きな数値や逆に小さな数値を指数を使って表記することもあります。例えば以下のものです。

```math
3.14 × 10^{3}\\
\\
5.1×10^{-2}
```
<font color=orange>（※）</font>上記の10<sup>-2</sup>は以下の通りです。

```math
10^{-2}=\frac{1}{10^{2}}
```
これをPythonで実装すると以下の通りになります。

```.py
>>> 3.14e3
3140.0
>>> 5.1e-2
0.051
```
ここで、e3は10<sup>3</sup>、e-2は10<sup>-2</sup>を意味します。

上記のような指数を使った浮動小数点数の表記については、よく**科学技術計算などで使われる**ことが多いです。

##演習問題
<font color="3333ff">
【1-1】以下の2進数を10進数に変換してください。（手計算で行ってください）
・10001010
・11111111
・10100100111010
</font>
<font color="3333ff">
【1-2】【1-1】の結果をPython Consoleにて確認してください。
</font>
<font color="3333ff">
【2-1】以下の16進数を10進数に変換してください。（手計算で行ってください）
・c3
・ff
・475
</font>
<font color="3333ff">
【2-2】【2-1】の結果をPython Consoleにて確認してください。
</font>
<font color="3333ff">
【3-1】以下の10進数を、2進数、8進数、16進数に変換してください。（手計算で行ってください
・31
・123
</font>
<font color="3333ff">
【3-2】【3-1】の結果をPython Consoleにて確認してください。
</font>

###[【目次リンク】へ戻る](https://qiita.com/ko0821/items/379e8bd9e6ea01089419)