1. 程式人生 > >正確的理解二進位制的原碼、反碼、補碼運算_01

正確的理解二進位制的原碼、反碼、補碼運算_01

原碼:計算機只能識別0和1,使用的是二進位制。數值有正負之分,計算機就用一個數的最高位存放符號(0為正,1為負),這就是機器數的原碼了。

下面的例子都假設字長為8個bits。

假如採用原碼來計算:

    (1) + (1)    //原碼計算

=(0000 0001) + (0000 0001)

=(0000 0010)

=(2)    //結果正確

    (1) - (1)    //原碼計算

=(1) + (-1)

=(0000 0001) + (1000 0001)

=(1000 0010)

=(-2)    //結果錯誤

    (1) - (2)//原碼計算

=(1) + (-2)

=(0000 0001) + (1000 0010)

=(1000 0011)

=(-3)    //結果錯誤

因為在兩個正數的加法運算中是沒有問題的。於是就發現問題出現在帶符號位的負數身上。

-------------------------------------------------------------------------------------------------------------

反碼:對為了解決原碼進行減法運算時出現的錯誤,引入了反碼的概念。對原碼中除符號位外的其餘各位逐位取反就產生了反碼。反碼的取值空間和原碼相同且一一對應。

反碼運算規則是從低位到高位逐列進行計算。0和0相加是0,0和1相加是1,1和1相加是0,但要產生一個進位1,加到下一列。

如果最高位相加後產生進位,則最後得到的結果要加1,即加上(0000 0001)。

用反碼運算,其運算結果亦為反碼。在轉換為真值時,若符號位為0,數位不變;若符號位為1,應將結果求反才是其真值。

假如採用反碼來計算:

    (1) - (1)    //反碼運算

=(1) + (-1)

=(0000 0001) + (1111 1110)    // -1 的原碼為(1000 0001),除符號位外各位取反得(1111 1110)

=(1111 1111)    //符號位為負,需對結果進行反碼轉換。

=(1000 0000)

=(-0)    //結果錯誤,0 應該是沒有符號的。

    (2) - (1)    //反碼運算

=(2) + (-1)

=(0000 0010) + (1111 1110)   + (0000 0001)  // -1 的原碼為(1000 0001),除符號位外各位取反得(1111 1110),最高位相加後產生進位,則最後得到的結果要加(0000 0001)。

=(0000 0001)  //符號位為正,不需要進行反碼轉換。

=(1)    //結果正確

----------------------------------------------------------------------------------------------------------------------

補碼:反碼運算中出現了(+0)和(-0)問題,在人們的計算概念中零是沒有正負之分的, 於是就引入了補碼概念。

負數的補碼就是對反碼加1,而正數不變,正數的原碼反碼補碼是一樣的。

假如採用補碼來計算:

    (1) - (1)

=(1) + (-1)

=(0000 0001)  + (1111 1110) + (0000 0001)    //(1000 0001)的反碼為(1111 1110),補碼等於反碼加1

=(0000 0000)

=(0)    //運算正確

所以直到引入補碼運算後才解決了上面出現的問題。