為什麼需要八進位制和十六進製制?
程式設計中,我們常用的還是10進製……必竟c/c++是高階語言。
比如:int a = 100,b = 99;
不過,由於資料在計算機中的表示,最終以二進位制的形式存在,所以有時候使用二進位制,可以更直觀地解決問題。
但,二進位制數太長了。比如int 型別占用4個位元組,32位。比如100,用int型別的二進位制數表達將是:
0000 0000 0000 0000 0110 0100
面對這麼長的數進行思考或操作,沒有人會喜歡。因此,c,c++ 沒有提供在**直接寫二進位制數的方法。
用16進製制或8進製可以解決這個問題。因為,進製越大,數的表達長度也就越短。不過,為什麼偏偏是16或8進製,而不其它的,諸如9或20進製呢?
2、8、16,分別是2的1次方,3次方,4次方。這一點使得三種進製之間可以非常直接地互相轉換。8進製或16進製制縮短了二進位制數,但保持了二進位制數的表達特點。
八進位制數的表達方法
c,c++語言中,如何表達乙個八進位制數呢?如果這個數是 876,我們可以斷定它不是八進位制數,因為八進位制數中不可能出7以上的阿拉伯數字。但如果這個數是123、是567,或12345670,那麼它是八進位制數還是10進製數,都有可能。
所以,c,c++規定,乙個數如果要指明它採用八進位制,必須在它前面加上乙個0,如:123是十進位制,但0123則表示採用八進位制。這就是八進位制數在c、c++中的表達方法。
由於c和c++都沒有提供二進位制數的表達方法,所以,這裡所學的八進位制是我們學習的,ctc++語言的數值表達的第二種進制法。
現在,對於同樣乙個數,比如是100,我們在**中可以用平常的10進製表達,例如在變數初始化時:
int a = 100;
我們也可以這樣寫:
int a = 0144; //0144是八進位制的100;乙個10進製數如何轉成8進製,我們後面會學到。
千萬記住,用八進位制表達時,你不能少了最前的那個0。否則計算機會通通當成10進製。不過,有乙個地方使用八進位制數時,卻不能使用加0,那就是我們前面學的用於表達字元的「轉義符」表達法。
八進位制數在轉義符中的使用
我們學過用乙個轉義符'/'加上乙個特殊字母來表示某個字元的方法,如:'/n'表示換行(line),而'/t'表示tab字元,'/''則表示單引號。今天我們又學習了一種使用轉義符的方法:轉義符'/'後面接乙個八進位制數,用於表示ascii碼等於該值的字元。
比如,問號字元(?)的ascii值是63,那麼我們可以把它轉換為八進值:77,然後用 '/77'來表示'?'。由於是八進位制,所以本應寫成 '/077',但因為c,c++規定不允許使用斜槓加10進製數來表示字元,所以這裡的0可以不寫。
十六進製制數的表達方法
如果不使用特殊的書寫形式,16進製制數也會和10進製相混。隨便乙個數:9876,就看不出它是16進製制或10進製。
c,c++規定,16進製制數必須以 0x開頭。比如 0x1表示乙個16進製制數。而1則表示乙個十進位制。另外如:0xff,0xff,0x102a,等等。其中的x也也不區分大小寫。(注意:0x中的0是數字0,而不是字母o)
以下是一些用法示例:
int a = 0x100f;
int b = 0x70 + a;
有一點很重要,c/c++中,10進製數有正負之分,比如12表示正12,而-12表示負12,;但8進製和16進製制只能用達無符號的正整數,如果你在**中里:-078,或者寫:-0xf2,c,c++並不把它當成乙個負數。
十六進製制數在轉義符中的使用
轉義符也可以接乙個16進製制數來表示乙個字元。如在6.2.4小節中說的 '?' 字元,可以有以下表達方式:
'?' //直接輸入字元
'/77' //用八進位制,此時可以省略開頭的0
'/0x3f' //用十六進製制
十六進製制轉十進位制(小數,負數)
十六進製制數和十進位制數類似,以小數點為界,整數部分從低位到高位依次是0次方位、1次方位、......、n次方位;小數部分從高位到低位依次是-1次方位、-2次方位、......、-m次方位。都可用加權求和的方式表示。十六進製制數轉換成十進位制數時,先用加權求和的方式表示出來,再將十六進製制數中的基數「10h」替換成對應的十進位制數值「16」,同時也將十六進製制數中的a、b、c、d、e、f替換成對應的十進位制數值10、11、12、13、14、15。然後完全用十進位制的規則計算出來,所得就是與該十六進製制數相等十進位制數。
例:1a6.3b8h
=1*10^2+a*10^1+6*10^0+3*10^(-1)+b*10^(-2)+8*10^(-3)
=1*16^2+10*16^1+6*16^0+3*16^(-1)+11*16^(-2)+8*16^(-3)
=419.232422
十進位制數轉
十六進製制
612.23
整數部分除16取整
612 / 16 = 38 ----- 4
38 / 16 = 2 ----- 6
2 / 16 = 0 ----- 2
餘數從下往上寫 ----- 264
小數部分乘16取整
0.23 * 16 = 3.68 --- 3
0.68 * 16 = 10.88 -- a
0.88 * 16 = 14.08 -- e
...整數從上往下寫 ----- .3ae
612.23(10) = 264.3ae(16)
結束了各種進製的轉換,我們來談談另乙個話題:原碼、反碼、補碼。
我們已經知道計算機中,所有資料最終都是使用二進位制數表達。
我們也已經學會如何將乙個10進製數如何轉換為二進位制數。
不過,我們仍然沒有學習乙個負數如何用二進位制表達。
比如,假設有一 int 型別的數,值為5,那麼,我們知道它在計算機中表示為:
00000000 00000000 00000000 00000101
5轉換成二制是101,不過int型別的數占用4位元組(32位),所以前面填了一堆0。
現在想知道,-5在計算機中如何表示?
在計算機中,負數以其正值的補碼形式表達。
什麼叫補碼呢?這得從原碼,反碼說起。
原碼:乙個整數,按照絕對值大小轉換成的二進位制數,稱為原碼。
比如 00000000 00000000 00000000 00000101 是 5的 原碼。
反碼:將二進位制數按位取反,所得的新二進位制數稱為原二進位制數的反碼。
取反操作指:原為1,得0;原為0,得1。(1變0; 0變1)
比如:將00000000 00000000 00000000 00000101每一位取反,得11111111 11111111 11111111 11111010。
稱:11111111 11111111 11111111 11111010 是 00000000 00000000 00000000 00000101 的反碼。
反碼是相互的,所以也可稱:
11111111 11111111 11111111 11111010 和 00000000 00000000 00000000 00000101 互為反碼。
補碼:反碼加1稱為補碼。
也就是說,要得到乙個數的補碼,先得到反碼,然後將反碼加上1,所得數稱為補碼。
比如:00000000 00000000 00000000 00000101 的反碼是:11111111 11111111 11111111 11111010。
那麼,補碼為:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
所以,-5 在計算機中表達為:11111111 11111111 11111111 11111011。轉換為十六進製制:0xfffffffb。
再舉一例,我們來看整數-1在計算機中如何表示。
假設這也是乙個int型別,那麼:
1、先取1的原碼:00000000 00000000 00000000 00000001
2、得反碼:11111111 11111111 11111111 11111110
3、得補碼:11111111 11111111 11111111 11111111
可見,-1在計算機裡用二進位制表達就是全1。16進製為:0xffffffff。
一切都是紙上說的……說-1在計算機裡表達為0xffffffff,我能不能親眼看一看呢?當然可以。利用c++ builder的除錯功能,我們可以看到每個變數的16進製制值。
十六進製制轉八進位制
時間限制 1.0s 記憶體限制 512.0mb 問題描述 給定n個十六進製制正整數,輸出它們對應的八進位制數。輸入格式 輸入的第一行為乙個正整數n 1 n 10 接下來n行,每行乙個由0 9 大寫字母a f組成的字串,表示要轉換的十六進製制正整數,每個十六進製制數長度不超過100000。輸出格式 輸...
十六進製制轉八進位制
問題描述 給定n 個十六進製制正整數,輸出它們對應的八進位制數。輸入格式 輸入的第一行為乙個正整數n 1 n 10 接下來 n行,每行乙個由 0 9 大寫字母 a f組成的字串,表示要轉換的十六進製制正整數,每個十六進製制數長度不超過 100000 輸出格式 輸出n 行,每行為輸入對應的八進位制正整...
十六進製制轉八進位制
資料很大 因此直接考慮用字串陣列來儲存十六進製制和八進位制 先根據 四位一體 的方法將十六進製制轉化為二進位制,而後根據 三位一體 將二進位制轉化為八進位制。include includeint main else if a i 1 else if a i 2 else if a i 3 else ...