如何轉換進位制(二進位/八進位/十進位/十六進位)

開始之前

關於進位制可以先參考 Wiki(中文),或者等我有空寫個筆記。簡單來說這就是個數字表示的方法,分為二進位、八進位、十進位與十六進位。進位表示遇到設定的數字就進位,以日常生活使用的十進位來說,就是遇到「十」就進位,所以 19 的下一個就是 20,十位數的 1 變成了 2。

十進位轉其他進位制

先從日常生活使用的十進位開始轉換,這邊轉換的邏輯根據整數與小數點有所不同,簡單來說就是:

  • 整數:除以進位制的數字,取得餘數與商數,並使用商數做為下一輪的被除數
  • 小數點:乘以進位制的數字,並取得整數的部分

以下皆以十進位制的 21.125 為例。

十進位轉二進位

進位制的數字為 2,所以:

整數 小數點
21 / 2 = 10 餘 1 0.125 * 2 = 0.25
10 / 2 = 5 餘 0 0.25 * 2 = 0.5
5 / 2 = 2 餘 1 0.5 * 2 = 1
2 / 2 = 1 餘 0 -

整數部分,開頭是最後一次運算的商,接著是最後一次運算的餘,並一路往回取得所有的餘數,如此一來取得 10101。小數點部分,取得第一次計算的整數部分後,一路往後取得所有整數,如此一來會取得 001。所以十進位的 21.125 就是二進位的 10101.001。

一個一個說明就是:

1
2
3
4
5
6
7
8
9
10
1 0 1 0 1. 0 0 1
| | | | | | | |
| | | | | | | +-- 0.5*2=1 的整數: 1
| | | | | | +---- 0.25*2=0.5 的整數: 0
| | | | | +------ 0.125*2=0.25 的整數: 0
| | | | +--------- 21/2=10 的餘,就是 1
| | | +----------- 10/2=5 的餘,就是 0
| | +------------- 5/2=2 的餘,就是 1
| +--------------- 2/2=1 的餘,就是 0
+----------------- 2/2=1 的 1

十進位轉八進位

進位制的數字為 8,所以:

整數 小數點
21 / 8 = 2 餘 5 0.125 * 8 = 1

如果計算不止一次,那取得資料的邏輯與方向跟轉二進位一樣(整數跟小數的部分都是)。這邊來說,十進位的 21.125 會轉成八進位 25.1。

十進位轉十六進位

進位制的數字為 16,所以:

整數 小數點
21 / 16 = 1 餘 5 0.125 * 16 = 2

如果計算不只一次,那取得資料的邏輯跟二進位一樣。這邊來說,十進位的 21.125 就會轉成十六進位的 15.2。

二進位轉其他進位制

接著從比較可能常見的二進位制轉成其他進位制,以十進位的 21.125 的二進位制 10101.001 為例,同樣分成整數與小數點,但根據轉換後是哪一種進位制,處理的方式又不同,這邊直接看各個轉換的介紹。

這邊使用十進位 21.125 轉出的二進位 10101.001 示範。

二進位轉十進位

先講二進位轉十進位是因為後續二轉八跟二轉十六都用得到二轉十的整數轉換概念。這邊的概念簡單講就是:

  1. 先確定次方數字:從個位數開始,次方數字為 0,位數越高,次方數字也越高(逐步 +1)。例如第三個數字,次方數字就是 2
  2. 將該位數的二進位數字(0 或者 1)乘以 2 的某次方,這個某次方的數字就是第一步取得的次方數字。以第三個數字來說,0 的話就是 0 乘以 2 的 2 次方

整數部分:

1
2
3
4
5
6
7
8
9
1 0 1 0 1
| | | | |
| | | | +-- 1*2^0 = 1
| | | +---- 0*2^1 = 0
| | +------ 1*2^2 = 4
| +-------- 0*2^3 = 0
+---------- 1*2^4 = 16

16 + 0 + 4 + 0 + 1 = 21

小數部分的規則跟整數的很類似,但小數點下第一位的次方數字是 -1,往後就逐步 -1,故小數點下第三位就是 -3。如此一來轉換的過程就是:

1
2
3
4
5
6
7
0 0 1
| | |
| | +-- 1*2^-3 = 1*(1/8) = 0.125
| +---- 0*2^-2 = 0*(1/4) = 0
+------ 0*2^-1 = 0*(1/2) = 0

0 + 0 + 0.125 = 0.125

組合以上兩者後得到十進位的 21.125。

二進位轉八進位

二進位轉八進位需要先將二進位分組,每三個數字為一組,不足的部分補 0,所以就是:

1
2
3
4
5
10101.001 -> 10 101.001 -> 010 101.001

010 當作整數的第一分區
101 當作整數的第二分區
小數點只有一個分區,就是 001

接著將各個分區當作獨立的二進位,並將他們轉成十進位的數字。整數部分的第一分區:

1
2
3
4
5
6
7
0 1 0
| | |
| | +-- 0*2^0 = 0
| |---- 1*2^1 = 2
+------ 0*2^2 = 0

故第一分區為 0 + 2 + 0 = 2

整數第二分區:

1
2
3
4
5
6
7
1 0 1
| | |
| | +-- 1*2^0 = 1
| +---- 0*2^1 = 0
+------ 1*2^2 = 4

故第二分區為 4 + 0 + 1 = 5

以上整數部分組合起來就是 25。接著是小數部分,小數點只有一個分區:

1
2
3
4
5
6
7
0 0 1
| | |
| | +-- 1*2^0 = 1
| |---- 0*2^1 = 0
+------ 0*2^2 = 0

故小數點第一分區為 0 + 0 + 1 = 1

以上組合起來,得出的八進位就是 25.1。要注意的是,小數點的轉換其實就整數一樣,只是轉換完畢後不要忘記他其實是小數點的部分.

二進位轉十六進位

跟轉八進位一樣要分組,但十六進位的分組是四個數字一組,不的部分補 0,所以 10101.001 會變成:

1
2
3
4
5
10101.001 -> 1 0101.001 -> 0001 0101.0010

0001 是整數的第一分區
0101 是整數的第二分區
小數點只有一個分區,就是 0010

轉換的方法一樣是將各分區當作獨立的二進位,並將他們轉成整數的十進位,只是不要忘記 0010 是小數點的部分。整數第一分區的轉換為:

1
2
3
4
5
6
7
8
0 0 0 1
| | | |
| | | +-- 1*2^0 = 1
| | +---- 0*2^1 = 0
| +------ 0*2^2 = 0
+-------- 0*2^3 = 0

故整數第一分區為 0 + 0 + 0 + 1 = 1

第二分區的轉換:

1
2
3
4
5
6
7
8
0 1 0 1
| | | |
| | | +-- 1*2^0 = 1
| | +---- 0*2^1 = 0
| +------ 1*2^2 = 4
+-------- 0*2^3 = 0

故整數第二分區為 0 + 4 + 0 + 1 = 5

小數點的部分:

1
2
3
4
5
6
7
8
0 0 1 0
| | | |
| | | +-- 0*2^0 = 0
| | +---- 1*2^1 = 2
| +------ 0*2^2 = 0
+-------- 0*2^3 = 0

故小數點的部分為 0 + 0 + 2 + 0 = 2

組合以上的結果,二進位的 10101.001 會轉成十六進位的 15.2。

八進位轉其他進位制

八進位轉其他進位制比較特殊,轉二跟轉十可以直接轉,但轉十六不行,得多一步,先轉成二進位,再轉成十六進位。

八進位轉二進位

將單個數字轉成二進位,並以 3bits 為一組(二進位轉八進位也是 3bits 一組)再全部組合起來就好。所以就是:

1
2
3
4
5
2 5 . 1
| | |
| | +-- 001
| +------ 101
+-------- 010

組合以上的就會變成 010101.001,也就是 10101.001。

八進位轉十進位

根據整數與小數點有不同的規則:

  • 整數:個位數為 0 次方,往高位數前進一個,次方就加一。例如第三位數的次方就是 2
  • 小數點:小數點下第一位為 -1 次方,往後前進次方就 -1

接著因為是八進位轉十進位,所以進位制的數字為 8。

1
2
3
4
5
6
7
2 5 . 1
| | |
| | +-- 1*8^-1 = 1*(1/8) = 1*0.125 = 0.125
| +------ 5*8^0 = 5
+-------- 2*8^1 = 16

以上整數的部分就是 16 + 5 = 21,加上小數點的部分就變成十進位的 21.125。

八進位轉十六進位

八進位轉十六進位無法直接轉換,需要先轉成二進位,再從二進位轉成十六進位。這邊就請參考兩個部分各自的介紹。結果就是:

1
八進位 25.1 -> 二進位 10101.001 -> 十六進位 15.2

十六進位轉其他進位制

十六進位轉二進位

同樣將各個數字轉成二進位,並以 4bits 為一組(二進位轉十六進位時也是 4bits 一組),再組合起來就好:

1
2
3
4
5
6
7
1 5 . 2
| | |
| | +-- 0010
| +------ 0101
+-------- 0001

組合以上就是 00010101.0010,省去多餘的 0 就變成 10101.001。

十六進位轉八進位

十六進位轉八進位無法直接轉換,需要先轉成二進位,再從二進位轉成十六進位。這邊請參考兩個部分各自的介紹。以結果來說就是:

1
十六進位的 15.2 -> 二進位的 10101.001 -> 八進位的 25.1

十六進位轉十進位

根據整數與小數點有不同的規則:

  • 整數:個位數為 0 次方,往高位數前進一個,次方就加一。例如第三位數的次方就是 2
  • 小數點:小數點下第一位為 -1 次方,往後前進次方就 -1

接著因為是十六進位轉十進位,所以進位制的數字為 16。

1
2
3
4
5
6
7
1 5 . 2
| | |
| | +-- 2*16^-1 = 2*(1/16) = 2*0.0625 = 0.125
| +------ 5*16^0 = 5
+-------- 1*16^1 = 16

組合以上兩者,最後得到十進位的 (16 + 5).125,也就是十進位的 21.125。