有關於反碼補碼的問題,以及很多初學者會經常問道 -128 的反碼和補碼的問題

1.       原碼反碼補碼概念以及轉換

 

1.1    原碼

原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其餘位表示值,例如:

原碼:[+1]0000 0001

原碼:[-1]1000 0001

1.2    反碼

正數的反碼是其本身

負數的反碼是在其原碼的基礎上, 符號位不變,其餘各個位取反.

原碼:[+1]0000 0001 反碼:0000 0001

原碼:[-1]1000 0001 反碼:1111 1110

1.3    補碼

正數的補碼就是其本身

負數的補碼是在其原碼的基礎上, 符號位不變, 其餘各位取反, 最後+1. (即在反碼的基礎上+1)

原碼:[+1]0000 0001 反碼:0000 0001 補碼:0000 0001

原碼:[-1]1000 0001 反碼:1111 1110 補碼:1111 1111

#include <stdio.h>

 

int main(int argc, const char * argv[])

{

//  其實數據存儲在內存中都是存儲的二進制

//  二進制又可以分爲原碼、反碼、補碼

//  其實最終存儲在內存中的是補碼

//    int4個字節 1個字節8所以整形就站 32

    int num = 12;

    /*

//     12的二進制

     12在內存中存儲的是它的補碼

     00000000  00000000 00000000 00001100

     正數:(三碼相同)正數的原碼就是它反碼,也是它的補碼

    

     -12

     二進制的最高位我們稱之爲符號位

     如果符號位是0代表是一個正數,

     如果符號位是1代表是一個負數

    

     10000000  00000000 00000000 00001100 (-12的原碼)

     11111111  11111111 11111111 11110011(反碼, 符號位不變其它位取反)

    

     11111111  11111111 11111111 11110011

    +00000000  00000000 00000000 00000001

     _____________________________________________

     11111111  11111111 11111111 11110100(補碼 , 反碼+1)

    

     結論:無論正數負數在內存中存儲的都是補碼

 

     11111111  11111111 11111111 11110101 (補碼)

    -00000000  00000000 00000000 00000001  (-1)

     _____________________________________________

     11111111  11111111 11111111 11110100 (反碼)

     10000000  00000000 00000000 00001011

    

     */

    printf("%d\n", 0b11111111111111111111111111110101);

    return 0;

}

 


 

2.       爲什麼要引入反碼、補碼?

 

 主要是爲了方便計算機計算,因爲計算機制作加法計算,沒有減法計算

     1、由於最高爲是符號位,如果是0就代表正數,如果是1就代表是負數

     2、如果直接存儲原碼,計算機在計算的時候還需要判斷最高位才能計算,效率較低

     3、爲了方便計算機計算,所以有了反碼和補碼,有了反碼和補碼之後,以後計算機就不需要判斷最高位,直接計算即可(計算機只做加法計算)

       1 + 1

       0001

     + 0001

     ————————

       0010 ==2

       1 - 1 == 1 + -1==計算機只會做加法

        0000 0001 原碼

     + 1000 0001 原碼

     ————————————————

       1000 0010 == -2

    

     1 - 1 == 1 + -1== 計算機只會做加法

       0000 0001 原碼(+1反碼)

     + 1111 1110 反碼

     ————————————————

       1111 1111 ==  反碼

     將計算出來的反碼轉爲原碼,再見原碼轉換爲十進制

     1000 0000 == 原碼 == -0

    

     1 - 1 == 1 + -1== 計算機只會做加法

       0000 0001 +1補碼)

     + 1111 1110 -1補碼)

     ——————————————————

     1 0000 0000 == 0 補碼

最後補充一點

這樣0[0000 0000]表示, 而以前出現問題的-0則不存在了.而且可以用[1000 0000]表示-128: (-1) + (-127) = [1000 0001] + [1111 1111] = [1111 1111] + [1000 0001] = [1000 0000]

-1-127的結果應該是-128, 在用補碼運算的結果中, [1000 0000]補碼就是-128. 但是注意因爲實際上是使用以前的-0的補碼來表示-128, 所以-128並沒有原碼和反碼錶示.(-128的補碼錶示[1000 0000]補算出來的原碼是[0000 0000], 這是不正確的)

有人會問 10000000這個補碼錶示的哪個數的補碼呢? 其實這是一個規定,這個數表示的是-128所以n位補碼能表示的範圍是 -2^(n-1)2^(n-1)-1 n位原碼能表示的數多一個

發佈了34 篇原創文章 · 獲贊 12 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章