1. 程式人生 > >再度理解原碼、反碼、補碼

再度理解原碼、反碼、補碼

很早就開始接觸這些熟悉又陌生的關鍵字,但是,時不時還會有錯:

看定義:

正數的原碼、反碼、補碼形式一致,負數的反碼為原碼的數值位取反,補碼為反碼+1也即是原碼的數值位取反再+1,計算機中以補碼錶示資料和運算

舉例:

+34原碼=反碼=補碼:00100010
-34原碼=10100010,反碼=11011101,補碼=11011110

直接來看一個題,程式碼:

int main(){
   int i=-2147483648;
   return printf("%d,%d,%d,%d",~i,-i,1-i,-1-i);
}
首先,-2147483648這個數為32位int所能表示的最小負整數,而如果原碼為 1000 0000  0000  0000  0000  0000  0000  0000(表示-0) ,其反碼應為數值位取反,符號位不變,即1111  1111  1111  1111  1111  1111  1111  1111,補碼為反碼+1 即為0 000 0000  0000  0000  0000  0000  0000 0000(最高位溢位,捨去),而+0 的原碼、反碼、補碼均為 0 000 0000  0000  0000  0000  0000  0000  0000,如果用 1000 0000  0000  0000  0000  0000  0000  0000作為 -2147483648的原碼,則會導致 -2147483648和0的補碼錶示一樣。

因此,計算機中規定用 1000 0000  0000  0000  0000  0000  0000  0000來作為 -2147483648的補碼,以確保-2147483648~2147483647都有唯一的補碼錶示;

所以:

1》~i:i的補碼為1000 0000  0000  0000  0000  0000  0000  0000,取反0111 1111 1111 1111 1111 1111 1111 1111,此為補碼,符號位為0,表示正數,正數原碼補碼一致,因而該數即表示231-1,即2147483647。

2》-i:要對一個數值執行單目運算子 -  表示的是對該數取反然後再+1,也即是我們常說的求補運算,注意這裡取反+1與原碼求補碼的區別!也就是求補運算與求補碼是不一樣的!題目中i的補碼為 1000 0000  0000  0000  0000  0000  0000  0000,取反+1,仍為 1000 0000  0000  0000  0000  0000  0000  0000,即    -2147483648

3》1-i  我們已經求出-i的補碼為1000 0000  0000  0000  0000  0000  0000  0000 加上1的補碼即為 1000 0000  0000  0000  0000  0000  0000  0001
該補碼錶示的原碼為1 111 1111  1111 1111 1111 1111 1111 1111,即為- 2147483647。

4》-1-i  -1的補碼為1 111 1111  1111 1111 1111 1111 1111 1111,加上-i補碼 1000 0000  0000  0000  0000  0000  0000  0000,
得 0111 1111  1111 1111 1111 1111 1111 1111,即 2147483647

弄懂以上內容,基本就差不多了!

賜教!