# Python Programming - Appendix 有的沒的
###### tags: `python-programming`
## Appendix 1. 進位制與進制轉換
### Appendix 1.1 進位制
[**進位制**](https://zh.wikipedia.org/zh-tw/%E8%BF%9B%E4%BD%8D%E5%88%B6)是一種計數方式,簡單來說,就是當我們在數數的時候,每數多少要進位一次的概念。因為人類有十根手指頭,所以人類最熟悉的計數方式是十進制,也就是每數十個數字要進位一次。
```
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, # 一次數十個數字
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, # 數了十下就進位
20, 21, ...
```
但世界上並不是只有十進制這種計數方式。小學的時候大家應該都選過小市長,選小市長在計票的時候我們會寫正字記號:
[](https://news.ltn.com.tw/news/politics/breakingnews/2623236)
> Figure a.1 歷史慘劇發生前數小時的高雄某開票所,正在使用正字記號計數系統。(2018,已上色)
「正」這個字有五筆劃,每寫下一個「正」就相當於計了 5 ,並且每寫完一個正我們就會開始寫下一個正,因此可以說,正字記號計數系統是一種**五進制**的系統。
```
0, 1, 2, 3, 4, # 一次數五個數字
10, 11, 12, 13, 14, # 數了五下就進位,可以把前面那個位數想成目前已經數完了幾個 5
20, 21, ...
```
其他還有像是時鐘是一種 60 進制系統、日曆是一種 365 進制系統、音樂的十二平均律是一種 12 進制系統等等,生活中其實充滿了各種不同的進位制。
電腦是利用電子元件的**高電位和低電位**來進行資料表示與運算的,由於只能區別這兩個狀態,因此你可以把電腦想成是一個只有兩根指頭的人。依照人類有十根指頭因此擅長十進制的邏輯來想,電腦自然而然就是一個擅長**二進制**的東西了。我們常常說電腦只懂 **0101** ,這裡的 0101 指的就是二進制數字的意思。對電腦來說,所有東西都是二進制數字。
雖然電腦只懂二進制數字,但是二進制對於有十根指頭的人類來說,實在是冗長到有點難以閱讀(1011011000010010 到底是多少???),因此人類為了方便,會將二進制數字**四個四個一組**閱讀,由於四個位數的二進制數字總共有 2<sup>4</sup> = 16 種組合,因此我們就稱這樣的表達方式叫作**十六進制**。
由於電腦在表達數字的方法上和人類原本的習慣有很大的差異,因此學習進制轉換是幫助我們了解電腦運作原理很重要的一環。
### Appendix 1.2 N 進制轉十進制
雖然生活中充滿不同的進位制,但其實他們本來的用意都是在數數用的。在面對一樣數量的東西時,儘管寫出來的數字不一樣,但這些不同的數字背後應該要代表相同的數量意義才對。舉個例子:

> Figure a.2 一籃蘋果。
:::warning
:thinking_face: **請問籃子當中有多少個蘋果呢?**
「啊,有 7 個蘋果呢。」
「我看倒是有 111 個蘋果。」電腦說。
「真像一塊塊綠豆糕。」一位外號叫「大食客」的同學緊接著說。
我們不禁哄堂大笑,同樣的一籃蘋果,每個人卻有不同的感覺。我想,這就是雅量吧。
~~(不是,到底怎麼看成綠豆糕的)~~
:::
這個籃子裡的蘋果數量,用不同的進位制來表示會寫出不一樣的數字
* 在十進制裏面,籃子裡有 7 個蘋果
* 在五進制裏面,籃子裡有 12 個蘋果
* 在二進制裏面,籃子裡有 111 個蘋果
為什麼會有這樣的差別呢?這就要回到「人們到底怎麼定義 $N$ 進制的?」這個問題來探討。
:::success
**Definition a.1** 對於一個 $N$ 進制系統來說,一個位數 (digit) 可以用 $N$ 種不同數字來表達,分別是 $0, 1, 2, ..., N - 1$。 如果有一個 $m$ 位的 $N$ 進制數字,叫作 $X$ ,我們把所有的位數由右到左分別令為 $x_0, x_1, x_2, ..., x_{m-1}$, 那這個數字代表的數值大小以十進制如何表示,就可以用下列算式計算
$$
X_{N} = x_{m-1} \times N^{m-1} + ... + x_2 \times N^2 + x_1 \times N^1 + x_0 \times N^0
$$
:::
以大家最熟悉的十進制舉例。在十進制當中,$N = 10$,每個位數只有可能是 0 - 9 十個數字的其中一個。假設有一個 $m = 3$ 位數的數字 $123$,那麼:
$$
123_{10} = 1 \times 10^{2} + 2 \times 10^1 + 3 \times 10^0 = 100 + 20 + 3 = 123
$$
現在你知道為什麼電腦會覺得上面這個籃子裡有 111 個蘋果了。
$$
111_{2} = 1 \times 2^{2} + 1 \times 2^1 + 1 \times 2^0 = 4 + 2 + 1 = 7
$$
利用定義 a.1 ,我們可以將任何進位制的數字都轉換成十進制,以便讓我們了解該數字實際上代表的數值大小是多少。
### Appendix 1.3 二進制與十六進制
在 [Appendix 1.1](#Appendix-11-進位制) 當中,我們有提到人類為了方便閱讀二進制數字,會將二進制數字**四個四個一組閱讀**,形成十六進制。這樣的操作使得二進制和十六進制要互轉是很容易的,你不必大費周章地把二進制數字轉換成十進制數字,再將該十進制數字轉換過去十六進制數字。
首先,我們要先知道十六進制到底有哪些數字。根據定義 a.1 ,十六進制系統每個位數會有 16 種不同的數字可以用,因為人類原本的計數系統只有十個數字,所以多出來的六個數字只好從別的地方借來用了。這 16 種數字分別是 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, **A, B, C, D, E, F** ,其中 A - F 分別代表 10 - 15。
接著,由於二進制數字每一個位數都只會有兩種可能,四位數的二進制數字就會有 2<sup>4</sup> = 16 種不同數字,剛好也會對應到十進制中的 0 - 15 。因此,十六進制、二進制和十進制數字之間會有一一對應的關係,如下表所示:
```
0 = 0000 = 0
1 = 0001 = 1
2 = 0010 = 2
3 = 0011 = 3
4 = 0100 = 4
5 = 0101 = 5
6 = 0110 = 6
7 = 0111 = 7
8 = 1000 = 8
9 = 1001 = 9
A = 1010 = 10
B = 1011 = 11
C = 1100 = 12
D = 1101 = 13
E = 1110 = 14
F = 1111 = 15
```
有了這個對應表,你現在可以快速的在二進制和十六進制之間自由切換了!
```
0b 1011 0110 0001 0010
= B 6 1 2
= 0xB612
0x9527
= 9 5 2 7
= 0b 1001 0101 0010 0111
```
## Appendix 2. 資料表示法
### Appendix 2.1 整數:二補數
### Appendix 2.2 浮點數: IEEE 754
### Appendix 2.3 字元: ASCII
## Appendix 3. 位元運算
### Appendix 3.1 邏輯閘
* 且
* 或
* 否
* 互斥或
* 位移
### Appendix 3.2 位元運算
### Appendix 3.3 位元運算的應用
* 奇偶數判斷
* x2 /2
* 大小寫轉換
* 更多花式技巧請參考 jserv 的講義(?)
## Appendix 4. 邏輯等價
### Appendix 4.1 且跟或的關係
### Appendix 4.2 「存在至少一個」和「所有的」的關係
### Appendix 4.3 邏輯等價
----
[<< Lec ?? - ???]() | [目錄](https://hackmd.io/@kaeteyaruyo/python-programming-index)