聊聊原碼、反碼和補碼那些事

眾所周知,數據在計算機中進行存儲,是採用了一定的編碼的。數據在計算機中可以用原碼、反碼和補碼進行表示。不過在開始介紹原碼、反碼和補碼之前,我需要先介紹兩個概念:機器數和真值。

機器數和真值

  • 機器數

所謂機器數就是一個數字在計算機中用二進制表示的形式。機器數是帶符號位,符號位為最高位,0表示正,1表示負。

例如:+進制數+3,其轉換為二進制數後為:0000 0011,而對於十進制數-3,其轉換為二進制數後為:1000 0011。這裡的0000 0011和1000 0011就是所謂的機器數。

  • 真值

所謂真值就是機器數所表示的真正的數值。因為機器數是包含符號位,所以轉換後的二進制成為形式值。

例如:1000 0001的形式值為129,但是其真正的數值為-1。所以,計算真值的時候,符號位僅僅用來表示該數值是正還是負,而無需參與數值的計算。

原碼、反碼和補碼的概念

首先,計算機存儲一個數是需要遵循一定的規則的,也就是所謂的編碼。而原碼、反碼和補碼就是計算機存儲數字的不同的編碼方式。

  • 原碼

所謂原碼就是不對機器數進行任何的轉換。其真值就是符號位加剩餘位數計算得出的數。

例如:+1的原碼是:0000 0001,-1的原碼是1000 0001。

對於原碼來說,由於第一位被用作了符號位,因此一個8位的二進制數,其表示範圍是[-127,127]。

至於轉換規則也很簡單,對於正數來說,其轉換後得到的二進制數就是其原碼。對於負數來說,只需將轉換後的二進制數的最高位變為1即可。

  • 反碼

所謂反碼就是,如果該數為正數,則無需進行任何轉換,如果該數是負數,則符號位保持不變,其餘位取反。

例如:+1的反碼是:0000 0001,-1的反碼是1111 1110。

對於反碼來說,與原碼類似,由於首位被用作了符號位,因此表示範圍也是[-127,127]。

從上述例子可以看出,若一個數為負數的時候,使用反碼錶示法無法直接得出該反碼所表示的真正的數值,需轉換為原碼後再進行計算。

反碼轉換為原碼的方式是:符號位保持不變,其餘位按位取反。

  • 補碼

所謂補碼就是,如果該數為正數,則無需進行任何轉換,如果該數是負數,則符號位保持不變,其餘位按位取反後加1,也就是先得到該數的反碼後加1。

例如:+1的補碼是:0000 0001, -1的補碼是:1111 1111。

對於補碼來說,雖然最高位也被用作了符號位,但是卻可以表示-128,因此其取值範圍是:[-128, 127]。

同樣的,若一個數為負數,使用補碼方式也無法直接得出該補碼所表示的真正的數值,也需要轉換為原碼後再進行計算。

補碼轉為原碼的方式是:先將補碼減1後,符號位保持不變,其餘位按位取反。

為何要使用反碼和補碼

通過上面的介紹,大家發現了一個問題,原碼是對人最好的一種編碼,那麼為何還要出現反碼和補碼呢?

首先,一個數值存入計算機後不僅僅是用來展示,還需要參與各種計算。如果是我們人來計算,則能很容易先將符號位進行隔離,先計算除符號位之外的剩餘位後再加入符號位。但是,對於計算機來說,則比較困難。最好的方法是讓符號位也參與運算。這樣類似1-1的問題就轉換為了1+(-1)的問題,也就是將減法轉換為了加法。

但是想法是好的,但是現實是殘酷的。用原碼來進行計算的時候總是無法得出正確的值。

當使用原碼進行計算的時候,例如:1 - 1 = 1 + (-1)= (0000 0001) + (1000 0001) = 1000 0010 = -2。

所以為了解決減法計算的問題,出現了反碼。

當使用反碼進行計算的時候,例如:1 - 1 = 1 + (-1)= (0000 0001) + (1111 1110) = 1111 11111

此時的1111 1111為反碼錶示形式,轉換為原碼為1000 0000,也就是-0。

雖然在我們的認知中,+0和-0都是0,但是對計算機而言,用兩個二進制數值來表示0則顯得有些不太合適。所以,用反碼錶示數值也並非盡善盡美。

所以為了解決+0和-0的表示問題,出現了補碼。

當使用補碼進行計算的時候,例如:1 - 1 = 1 + (-1) = (0000 0001) + (1111 1111)= (1)0000 0000 。由於超出了表示位數,本該存在的最高位的1會丟掉,所以得出的結果為:0000 0000。

此時的0000 0000為補碼,轉換為原碼後為0000 0000,其值為0,符合預期結果。

再例如:-1 - 127 = (-1) + (-127)= (1111 1111) + (1000 0001)= (1)1000 0000。同理,最高位1會發生丟失,所以得出的結果為:1000 0000。

此時的1000 0000為補碼,恰好可以呀用來表示-128.不過需要強調的是,正因為用補碼錶示的-128轉換後得到原碼為-0,所以-128只有補碼的表示形式。

自此,關於原碼、反碼和補碼的介紹就已經完畢了,希望大家都能掌握。


分享到:


相關文章: