在計算機中,定點數的編碼主要有三種表示形式:原碼、補碼、移碼。
一、原碼是最容易理解的編碼方式。用最高位表示正負,0 表示正數,1 表示負數。即設最高爲位n,則符號位爲 。
Decimal | Binary | Decimal | Binary | |
0 | 0000 | -0 | 1000 | |
1 | 0001 | -1 | 1001 | |
2 | 0010 | -2 | 1010 | |
3 | 0011 | -3 | 1011 | |
4 | 0100 | -4 | 1100 | |
5 | 0101 | -5 | 1101 | |
6 | 0110 | -6 | 1110 | |
7 | 0111 | -7 | 1111 |
顯而易見地,用源碼錶示時,0 的表示不唯一,不利於程序員編程。另外,這種編碼會導致加減運算方式無法統一,特別是當 a < b時,實現 a - b 比較困難,由於還要對額外的符號位進行處理,故不利於硬件的實現。
二、補碼
相信各位對補碼都不陌生,都知道補碼的一條換算規則是:正數的補碼和原碼一樣;負數的補碼則是,符號位不變,其餘位數取反,最後加一。但是爲什麼換算是這樣的呢?補碼到底是什麼呢?爲什麼要用補碼錶示呢?
1. 先解釋一下補碼到底是什麼。
補碼的存在是依附於模運算系統的。在模運算系統中,一個數與它除以 “模” 後的餘數等價。
例如我們生活中的時鐘便是一種模 12 系統。
假定鐘錶時鐘指向 10 ,要將它撥向 6 ,可以有兩種方法
(1)逆時針撥動 4 格 : 10 - 4 = 6
(2)順時針撥動 8 格: 10 + 8 = 18 6
在這個時鐘的模 12 系統中 10 - 4 10 + 8 (mod 12) 也就是 -4 8 (mod 12)
則稱 8 是 -4 對模 12 的補碼( -4 的模 12 補碼等於 8),同樣的 -3 9 (mod 12)
從這裏我們可以得到 結論一:一個負數的補碼等於模減去該負數的絕對值 ( 10 - |-4| = 10 - 4 )
根據結論一,我們可以推出我們慣常使用的規則是怎麼運算出來的了。看下面這個例子:
我想,現在小夥伴們應該知道我們平時使用的換算規則是怎麼回事了。在這裏,我還要推薦一個更簡便的方法給大家:
從右到左遇到第一個 1 的前面各位取反。
還是上面 -123 這個例子好了。 -0111 1011 從右到左遇到的第一個 1 是 0 號位上的 1,因此,0 號位上的 1 不變,1~7號位上各位取反,得到 1000 0101
2. 在模運算系統中,爲什麼可以將減法運算統一成加法運算。
我們先用 “4 位 十進制” 模運算系統做例子。
從我們換算成補碼的過程中就窺探出減法運算轉化成加法運算的原因。當然,上面這個只是我自己的理解,如果小夥伴們有其他的理解一定要記得留言,因爲我不清楚這個思路有沒有錯誤。(/抱拳)
在計算機中,我們採用的是二進制,但是思想和做法都是相同的。例如
3. 爲什麼在計算機中大部分用補碼錶示數值呢?
因爲計算機的運算器只有有限位,就像我們表示數值一樣,一個byte 只有 8 位,超過 8 位就會溢出。假設爲 n 位,那麼運算結果只能保留低 n 位,即是一種模爲 的模運算系統。
4. 特殊數的補碼
假定機器數有 n 位(例子中 n = 4)
5. 變形補碼( 4's comlement)
變形補碼就是用兩個符號位的補碼,主要用於存放運算過程中的中間結果。因爲在運算過程中,可能會出現溢出現象,用變形補碼進行數據存儲可以防止在運算過程中的溢出,從而儘量減少對最終結果的干擾(只要最終結果不溢出就可以了)。
Decimal | 補碼 | 變形補碼 | Decimal | 取反 | 補碼 | 變形補碼 |
0 | 0000 | 0 0000 | -0 | 1111 | 0000 | 0 0000 |
1 | 0001 | 0 0001 | -1 | 1110 | 1111 | 1 1111 |
...... | ...... | ...... | ...... | ...... | ...... | ...... |
7 | 0111 | 0 0111 | -7 | 1000 | 1001 | 1 1001 |
8 | 1000 | 0 1000 | -8 | 0111 | 1000 | 1 1000 |
4's comlement 指雙符號位,因爲雙符號位中 = 4 ,同樣的,我們前面介紹的補碼則是 單符號位 2's comlement 。
在上面表格中我們可以看到, 8 的值太大,用 4 位補碼無法表示,會出現溢出,但變形補碼可以保留符號位和最高數值位。可以理解成在變形補碼中,最高位爲符號位,次高位可以用於表示數值。
要注意的是,+0 和 -0 的變形補碼錶示方式是一樣的。
三、移碼
移碼的命名其實已經向我們解釋了他的表示方法了。
移碼錶示是將每一個數加上一個偏置常數(Excess / bias),通常,當編碼位數爲 n 時,bias 取值爲 或者 -1 ( 例 IEEE 754 )。
其中,當bias 取 時,移碼與補碼僅第一位不同。
移碼的作用:用移碼錶示浮點數的階。
因爲大多數計算機會採用科學計數法對浮點數進行存儲,因此浮點數的大小比較一大部分是階(指數)的比較,移碼的加入會簡化對指數的比較。例如: