資料表示法與數字系統
一補數(one's complement)
一補數是有號二進位的第二次歷史嘗試,是介於符號-數值法與我們今天用的二補數之間的踏腳石。規則漂亮得簡單:要取一個數的負,就翻轉每個位元——把每個 0 變成 1、每個 1 變成 0。所以若 +5 在 8 位元裡是 0000 0101,那麼 -5 就是它逐位翻轉後的 1111 1010。最左邊的位元仍然扮演符號指示(1 代表負),但它不像符號-數值法那樣被單獨儲存;是整個圖樣被反轉。
翻轉位元解決了符號-數值法的一個頭痛,卻製造了一個新的。好消息是:加法好用許多,因為一個數加上它翻轉後的形式行為合理。陷阱是「環繞進位」——把兩個一補數相加時,任何從左端掉出去的進位都必須加回到右端,這是硬體必須執行的額外步驟。而舊的詛咒還在:仍然有兩個零。全 0(0000 0000)是正零,全 1(1111 1111)也就是零的翻轉是負零。那個多餘的圖樣浪費了一個值,也使比較變複雜。
一補數曾用於一些真實機器(例如早期的 CDC 大型主機),而它至今仍冒頭於一個著名角落:網際網路 IP、TCP、UDP 協定裡的檢查碼,就是用一補數算術(連同環繞進位)計算的。不過對於一般整數儲存,它被二補數取代了,後者一舉消除了第二個零與環繞進位。誠實的總結:一補數是「差一點」——比符號-數值法更接近,卻仍離理想差一步調整。
在 8 位元一補數裡,+5 是 0000 0101,-5 是它的翻轉 1111 1010。把它們相加得到 1111 1111——這是負零,而非你也許期待的正零,正顯示了雙重零的惱人之處。
翻轉每個位元即取負;但雙重零與環繞進位仍在。
一補數仍有兩個零、且需環繞進位,所以二補數在整數上取代了它。它殘存在網際網路檢查碼(IP/TCP/UDP)裡,那是以一補數算術定義的。
又稱
另見