C語言中文網 目錄
首頁 > 編程筆記 > C語言筆記 閱讀:6,273

進制轉換

所謂進制轉換,就是將一種進制的數字轉換為另一種進制的數字。數字的表示形式雖然改變了,但是數字的值并沒有變。

這里我們講解兩種方法,第一種是簡單的口算法,第二種是復雜的公式法。

進制轉換口算法

我們來思考一個問題:為什么八進制數 17 對應的十進制數是 15?我們看八進制數 17 中的 7,這個 7 是沒有進位的,它同十進制數 7 是一樣的,因為它是在個位。而八進制數 17 中的 1,它能進一是因為有 8 才進一的,所以這個 1 代表的就是十進制的 8。所以一個 8 和一個 7 加起來就是 15,這就是為什么八進制數 17 對應的十進制數是 15 的原因。

現在我來考考讀者,看讀者能不能立刻回答出來。八進制數 23 對應的十進制數是多少?十進制數 34 對應的八進制數是多少?

同樣,八進制數 23 中的 3 和十進制數 3 是一樣的,而 2 說明進了兩次位,有 8 才能進一次,進了兩次說明是十進制的 16,所以 16 和 3 加起來就是 19。因此八進制數 23 對應的就是十進制數 19。

十進制數 34 里有 4 個 8,余 2,所以十進制數 34 對應的就是八進制的 42。

我再來問問大家,看大家能不能舉一反三:十六進制的 3D 對應的十進制是多少?十進制的 83 對應的十六進制是多少?

方法是相同的,十六進制數 3D 中的 D 表示的是十進制的 13,而十六進制達到 16 才能進一次,數字 3 說明進了 3 次,即 48,13 和 48 加起來就是 61。因此,十六進制數 3D 就對應十進制數 61。同樣,十進制 83 中有 5 個 16,余 3,所以十進制數 83 就是十六進制數 53。

如果是八進制和十六進制相互轉換的話,因為它們都跟十進制有關系,所以可以將十進制當作一個橋梁,先轉換成十進制,然后再轉換成另一個進制。

以上的口算方法實際上就是進制轉換的本質和奧秘的總結。但是用口算方法只能計算比較小的數字,當數字比較大的時候還是得在紙上算。之所以沒有講如何用口算進行二進制轉換,原因就是二進制的計算量很大,不適合口算。介紹口算方法的主要目的是想讓大家體會進制轉換的本質,從而能夠深刻理解下面所講的公式法。

進制轉換公式法

以上講的是進制轉換的本質,下面系統地講一下進制轉換。在閱讀本節之前建議大家先掌握上節的內容,這樣效率會更高,理解會更深刻。

1) r 進制轉換成十進制

r 進制數 an an–1…a1 a對應的十進制數為:

an×r+ an–1×rn–1 + … + a1×r+ a0×r0

下面給大家舉幾個例子:
  • (1011011)2=1×26+0×25+1×24+1×23+0×22+1×21+1×20=64+0+16+8+0+2+1=91
  • (356)8=3×82+5×81+6×80=192+40+6=238
  • (2FB)16=2×162+15×161+11×160=512+240+11=763

2) 十進制轉換成 r 進制

方法:除 r 取余數,直至商為零,余數倒序排序。

下面給大家舉個例子:十進制 185 分別轉換成二進制、八進制和十六進制。


所以(185)10=(10111001)2


所以(185)10=(271)8


(185)10=(B9)16

3) 進制之間的轉換

上面講了十進制和r進制之間的相互轉換。可以說十進制是任意進制間相互轉換的橋梁,任何進制都可以先轉換成十進制,然后再轉換成需要的進制。

但二進制和八進制、二進制和十六進制之間的相互轉換可以直接計算。二進制的運算首先要記住竅門:8421。(1111)2=1×23+1×22+1×21+1×20=8+4+2+1,即二進制數 1111 從左到右每一位分別代表十進制的 8、4、2、1。

① 二進制轉換為八進制

將二進制數從右到左,每三位組成一組,最左邊不足三位的補零。然后對每組分別運用 8421 法則快速運算。如果二進制是 1 則保留,如果是 0 則舍去。比如:
  • (1111)2=8+4+2+1=15
  • (1010)2=8+0+2+0=10
  • (1100)2=8+4+0+0=12
  • (0101)2=0+4+0+1=5

所有的二進制轉其他進制的運算都要記住這個法則。如果是二進制轉十進制,且二進制數多于四位,那么其他位依次為 16、32、64、128……

只不過二進制轉八進制時,因為是每三位為一組,所以就不存在第四位,這樣 8 就都為 0 了,所以其實是 421 法則,但統一記為“8421”更順口。

【練習】(11001011)2=(?)8

首先,從右到左分成三組,最左邊不足三位的補零,即 011001011。然后對每組分別運用“8421”快速運算即 313。所以(11001011)2=(313)8

② 二進制轉換為十六進制

將二進制數從右到左,每四位組成一組,最左邊不足四位的補零。然后對每組分別運用“8421”法則快速運算。

【練習】(1011001011)2=(?)16

首先,從右到左分成四組,最左邊不足四位的補零,即 001011001011。然后對每組分別運用“8421”法則快速運算即 2 C B。所以(11001011)2=(2CB)16

③ 八進制轉換為二進制

對于每一位八進制數,分別運用“8421”法則快速運算,逐位展開成三位二進制數,不足三位的補零,最后最左邊的零可省略。

【練習】(3754)8=(?)2

(3)8=(011)2,(7)8=(111)2,(5)8=(101)2,(4)8=(100)2,所以(3754)8=(11111101100)2

④ 十六進制轉換為二進制

對于每一位十六進制數,分別運用“8421”法則快速運算,逐位展開成四位二進制數,不足四位的補零,最后最左邊的零可省略。

【練習】(4B39F)16=(?)2

(4)16=(0100)2,(B)16=(1011)2,(3)16=(0011)2,(9)16=(1001)2,(F)16=(1111)2,所以(4B39F)16=(1001011001110011111)2

最后還有一個“小數部分的進制轉換”,這個幾乎用不到,所以就不講了,要是以后用到了再看也不遲。

接下來給大家寫一個程序。這個程序的功能是將同一個十進制數以不同的進制顯示出來。這個程序大家暫時還看不懂,沒關系,等學到后面再來看這個程序就很簡單了。
#include <stdio.h>
int main(void){
    int i = 63;
    printf("i = %d\n", i);
    printf("i = %o\n", i);
    printf("i = %x\n", i);
    printf("i = %X\n", i);
    return 0;
}
運行結果:
i = 63
i = 77
i = 3f
i = 3F

其中:%d表示以十進制輸出;%o表示以八進制輸出,注意是字母 o 不是數字 0,而且一定是小寫字母。這與前面講的八進制數是數字 0 而不是字母 o 正好是相反的,千萬不要弄混了。

%x%X表示以十六進制輸出。那么它們有什么區別呢?如果是 %x 那么字母就是以小寫的形式輸出,如果是 %X 那么字母就是以大寫的形式輸出。這也是八進制中只有 %o 沒有 %O 的原因,因為八進制中根本沒有字母,所以不需要區分大小寫。

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo