計算機中的“數”,花樣很多,又是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,隻要把這最高位變化一下,補碼就可以變成移碼,同樣,移碼也可以由此變成補碼。