原碼,反碼,補碼[轉(zhuǎn)]文章分類:C++編程[轉(zhuǎn)載]http://shychj-chjshy.blog.sohu.com/73142224.html
1、原碼、反碼和補碼的表示方法 (1) 原碼:在數(shù)值前直接加一符號位的表示法。 例如: 符號位 數(shù)值位 [+7]原= 0 0000111 B [-7]原= 1 0000111 B 注意:a. 數(shù)0的原碼有兩種形式: [+0]原=00000000B [-0]原=10000000B b. 8位二進制原碼的表示范圍:-127~+127 (2)反碼: 正數(shù):正數(shù)的反碼與原碼相同。 負數(shù):負數(shù)的反碼,符號位為“1”,數(shù)值部分按位取反。 例如: 符號位 數(shù)值位 [+7]反= 0 0000111 B [-7]反= 1 1111000 B 注意:a. 數(shù)0的反碼也有兩種形式,即 [+0]反=00000000B [- 0]反=11111111B b. 8位二進制反碼的表示范圍:-127~+127 (3)補碼的表示方法 12)補碼的表示: 正數(shù):正數(shù)的補碼和原碼相同。 負數(shù):負數(shù)的補碼則是符號位為“1”,數(shù)值部分按位取反后再在末位(最低位)加1。也就是“反碼+1”。 例如: 符號位 數(shù)值位 [+7]補= 0 0000111 B [-7]補= 1 1111001 B 補碼在微型機中是一種重要的編碼形式,請注意: a. 采用補碼后,可以方便地將減法運算轉(zhuǎn)化成加法運算,運算過程得到簡化。正數(shù)的補碼即是它所表示的數(shù)的真值,而負數(shù)的補碼的數(shù)值部份卻不是它所表示的數(shù)的真值。采用補碼進行運算,所得結(jié)果仍為補碼。 b. 與原碼、反碼不同,數(shù)值0的補碼只有一個,即 [0]補=00000000B。 c. 若字長為8位,則補碼所表示的范圍為-128~+127;進行補碼運算時,應注意所得結(jié)果不應超過補碼所能表示數(shù)的范圍。 2.原碼、反碼和補碼之間的轉(zhuǎn)換 由于正數(shù)的原碼、補碼、反碼表示方法均相同,不需轉(zhuǎn)換。 在此,僅以負數(shù)情況分析。 (1) 已知原碼,求補碼。 例:已知某數(shù)X的原碼為10110100B,試求X的補碼和反碼。 解:由[X]原=10110100B知,X為負數(shù)。求其反碼時,符號位不變,數(shù)值部分按位求反;求其補碼時,再在其反碼的末位加1。 1 0 1 1 0 1 0 0 原碼 1 1 0 0 1 0 1 1 反碼,符號位不變,數(shù)值位取反 1 +1 1 1 0 0 1 1 0 0 補碼 故:[X]補=11001100B,[X]反=11001011B。 (2) 已知補碼,求原碼。 分析:按照求負數(shù)補碼的逆過程,數(shù)值部分應是最低位減1,然后取反。但是對二進制數(shù)來說,先減1后取反和先取反后加1得到的結(jié)果是一樣的,故仍可采用取反加1 有方法。 例:已知某數(shù)X的補碼11101110B,試求其原碼。 解:由[X]補=11101110B知,X為負數(shù)。求其原碼表示時,符號位不變,數(shù)值部分按位求反,再在末位加1。 1 1 1 0 1 1 1 0 補碼 1 0 0 1 0 0 0 1 符號位不變,數(shù)值位取反 1 +1 1 0 0 1 0 0 1 0 原碼 #include<stdio.h> void main() { short int tt = 65535 ; //unsigned short int tt = 0XFF43; printf("size of is %d\n",sizeof(tt)); printf("%0X\n",tt); printf("%d\n",tt); } 結(jié)果: size of is 2 FFFFFFFF -1 輸出FFFFFFFF 是因為在第2個Printf,傳遞參數(shù)的時候,系統(tǒng)將Short int 自動轉(zhuǎn)化為Int . #include<stdio.h> void main() { short int tt = -1 ; //unsigned short int tt = 0XFF43; printf("size of is %d\n",sizeof(tt)); printf("%0X\n",tt); printf("%u\n",(unsigned short int)tt); } 輸出: size of is 2 FFFFFFFF 65535 ############################ int main(void) { unsigned int un = 3000000000; /* 我使用的編譯器 int 是 32 位的 */ short end = 200; /* 而 short 是 16 位的 */ long big = 65537; printf("un = %u and not %d\n", un, un); printf("end = %hd and %d\n", end, end); printf("big = %ld and not %hd\n", big, big); printf("Press ENTER to quit..."); getchar(); return 0; } 程序輸出結(jié)果如下: un = 3000000000 and not -1294967296 end = 200 and 200 big = 65537 and not 1 Press ENTER to quit... 這個程序表明,錯誤使用格式限定符會導致意想不到的輸出。首先,錯誤使用 %d 來做無符號整型變量 un 的格式限定符,導致輸出的是負數(shù)。這是因為我的計算機使用相同的二進制形式來表示 3000000000 和 -129496296 ,而計算機只認識二進制。所以,如果我們使用 %u 告訴 printf 輸出無符號整數(shù),輸出的就是 3000000000;如果我們誤用了 %d,那么輸出的就是一個負數(shù)。不過,如果我們把代碼中的 3000000000 改成 96 的話,輸出就不會出現(xiàn)異常。因為 96 沒有超出 int 的表示范圍。 然后,對于第二個 printf,無論我們使用 %hd 還是 %d,輸出的結(jié)果都是一樣的。這是因為 C 語言標準規(guī)定,當 short 類型值傳遞給函數(shù)時,要自動轉(zhuǎn)化成 int 類型值。之所以轉(zhuǎn)化成 int,是因為 int 被設(shè)計為計算機處理效率最高的整數(shù)類型。所以,對于 short 和 int 大小不同的計算機來說,把變量 end 轉(zhuǎn)化成 int 類型再傳遞給函數(shù),速度更快。如此說來,h 好像沒有存在意義。其實不然。我們可以用 %hd 來看看較大的整數(shù)類型被截斷成 short 類型的時候會是什么樣的。 而第三個 printf,由于誤用 %hd,導致輸出是 1。這是因為,如果 long 是 32 位的話,65537 的二進制形式便是 0000 0000 0000 0001 0000 0000 0000 0001,而 %hd 命令 printf 輸出 short 類型的值,從而導致 printf 只處理 16 位數(shù)據(jù)(假設(shè) short 是 16 位的),最終導致輸出 1。 |
|