天天看點

移碼和補碼

計算機中的“數”,花樣很多,又是ASCII碼、又是BCD碼等等,下面,做而論道寫了一些關于移碼、補碼的一些看法,歡迎拍磚。

機器數

計算機中的“數”,其實都不是數字,它們都是一些高、低電平。

其中,高電平為3.2~5.0V,記為1,低電平為0~0.3V,記為0。

這些1、0,顯然都不應該稱為“數”,應該稱為“數位”,稱為“機器數”更合适一些。

用8位“數位”,可以形成0000 0000 ~ 1111 1111 共 256 種不同的組合,用16進制表示就更簡練一些,把它們像數字一樣寫在一個數軸上,如下圖所示:

移碼和補碼

無符号數

用這些“機器數”代表人們常用的“數字”,還是很容易了解的,特别是無符号數 0 ~ 255,不用經過任何變換,直接對應就可以了,如下圖所示:

移碼和補碼

有符号數

但是,用“機器數”代表“有符号數”,就要費些心思了,這也是被人弄的很濫的部分。

8位二進制數共有 256 種組合,可以用 128 個代表負數,用128 個代表零和正數,那麼“有符号數”的範圍就是:-128 ~ -1 、0 ~ +127,畫在數軸上如下所示:

移碼和補碼

移碼

最簡單的代表方式是“移碼”。

“移碼”就是把所有的數字都加上 128,也就是把 -128 ~ +127 的範圍的數字,都平移到 0 ~ 255 範圍内,然後再用 0 ~ 255 的“機器數”來表示。

當有符号數和機器數的對應關系如下圖時,這就是“移碼”:

移碼和補碼

顯而易見,機器數0 ~ 127 代表負數 -128 ~ -1,機器數128 ~ 255 代表 0 ~ 127。所有的數字都右移了128,大概這就是“移碼”名稱的來源吧。

已知一個數 X,其 8 位字長的移碼定義為:

    [X]移 = 128 + X                -128  <=  X  <=  127

有興趣的讀者可以去檢視計算機類的書籍,從中可以找到這個式子。

移碼,應用的場合還是很多的。多數AD轉換器産生的數字,就是用移碼表示采樣資料的。另外在浮點數中,也有應用。

補碼

移碼雖然解決了表示負數的難題,但是它是把全部數字都向右邊移動了 128,正數也都變大了,這就不友善進行數字的計算。

為此,有人提出了“補碼”的表示方式,即零和正數不用移動,隻是把負數向右移動 256 個位置。

關于補碼的由來,可見:

http://hi.baidu.com/%D7%F6%B6%F8%C2%DB%B5%C0/blog/item/d92cc986c2a1523bc75cc380.html

下圖就是補碼中負數和機器數的對應關系:

移碼和補碼

下圖又加上了正數和機器數的對應關系:

移碼和補碼

可見,機器數0 ~ 127 代表零和正數0 ~ 127,機器數128 ~ 255 代表負數 -128 ~ -1。

已知一個數 X,其 8 位字長的補碼定義為:

      /  X                                   0  <=  X  <=  +127 ;0和正數不用變化

  [X]補 = |

      \ 2 ^ 8 -| X |   =   256  +  X        -128 <= X < 0 ;負數就加256

有興趣的讀者可以去檢視計算機類的書籍,從中也可以找到這個式子。

從定義式求一個數的補碼是非常容易的:是正數就直接變成二進制,是負數先加上256(就變成128~255了)再變成二進制就完了。

補碼和移碼的互換

從前面的示意圖中可以看出,在移碼、補碼中,僅僅是正數、負數交換了位置,而正數、負數中數字的次序并沒有變。

因為機器數0 ~ 127 的最高位都是0,機器數128 ~ 255 的最高位都是1,隻要把這最高位變化一下,補碼就可以變成移碼,同樣,移碼也可以由此變成補碼。