計算機中的補碼與java取反運算

linweibin95發表於2016-12-26

什麼是補碼?

    計算機中的符號數有三種表示方法,即原碼、反碼和補碼。
    三種表示方法均有符號位和數值位兩部分,最高位即最左位為符號位,用0表示“正”,用1表示“負”。
    *在計算機系統中,數值一律用補碼來表示和儲存。
    原因在於,使用補碼,可以將符號位和數值域統一處理;同時,加法和減法也可以統一處理。
    此外,補碼與原碼相互轉換,其運算過程是相同的,不需要額外的硬體電路。

怎樣求補碼?

    正整數的補碼是其二進位制表示,與原碼相同。
    負整數的補碼,先將其當作正整數,然後將其轉成二進位制,再將其所有位取反(包括符號位,0變1,1變0)後加1,即求得補碼。
    例題:現在有一個二進位制數為11111111 11111111 11111111 11111010,求它的十進位制表示。
分析:最高位為1,為負數,問題轉化為:現知其為一負數的補碼,求該負數。
    11111111 11111111 11111111 11111010 - 1=
    11111111 11111111 11111111 11111001
    取反:
    00000000 00000000 00000000 00000110
    結果為6.即為該負數對應正數數值為6。
    即該負數為-6.

java中的取反運算

規則:取反操作——原為1,得0;原為0,得1。(1變0; 0變1)

例子:(java中正整數預設數值型別為int型別,即4byte,32bite)
“5”進行取反運算:
二進位制表示:00000000 00000000 00000000 00000101
全部位取反:11111111 11111111 11111111 1111101

這個11111111 11111111 11111111 11111010,它的十進位制表示是多小呢?
分析:最高位為1,為負數,問題轉化為:現知其為一負數的補碼,求該負數。
11111111 11111111 11111111 11111010 - 1=
11111111 11111111 11111111 11111001
取反:
00000000 00000000 00000000 00000110
結果為6.即為該負數對應正數數值為6。
即該負數為-6.

    即“5”進行取反操作,結果為“-6”。
練一練:
“6”進行取反操作,結果為“-7”。

重點:計算機為啥使用補碼?

    假設現在有一個只能實現4位的加法器,4個二進位制位能表示的數有16個,最大的數是15,最小的是0.
    現在進行加法運算。
    4+3=0100+0011=0111=7(運算正確)
    11+8=1011+1000=0011=3(數值溢位,本來為10011,現在溢位位被捨棄)
    只要數值在規定的範圍內,這個加法器完全可以工作起來。為了節省CPU的電路設計,可不可以在加法器中實現減法運算?答案是可以的!
    先引入一個補數的概念,在4位的加法器中,1的補數是15,2的補數是14,3的補數是13,發現沒有,原數和其補數和為16.
舉例:
    11+8=1011+1000=0011=3
    11-8=3
    神奇的現象發生了,一個數減去另一個數的值等於一個數加上另一個數的補數。
    不信你可以自己試試。如我們身邊的鐘表,從6點退回到3點,可以往後退三格,也可以往前走9格。
    那在二進位制的世界裡如何求補數呢?沒錯,就是“補碼”!原碼取反再加一為補碼。多麼巧妙!
    11+8=1011+1000=0011=3
    11-8=1011+1000=0011=3(補碼1000,原碼是-8)
    發現沒有?所謂的“原碼取反再加一為補碼”是針對負數來的,即一開始這個規矩就是解決加法器中的減法運算問題的,所以不關正整數的事。
    “計算機中數值以二進位制的補碼形式儲存,
    正整數的補碼是本身,
    負整數的補碼是先將其當作正整數,轉成二進位制,再將其所有位取反(包括符號位,0變1,1變0)後加1,即求得補碼”。
    當然在一些情況下,沒有負數出現,所以就有了無符號數。

以上部分內容寫作思路參考自公眾號:碼農翻身,微訊號:coderising.本文僅是個人筆記。侵刪。

相關文章