補碼運算的基本公式如下:
當進行補碼運算的時候,不可避免會產生溢出問題:
上圖中,+89和+108的符號位都是0,最高數值位都是1,最高數值位產生進位,前者不產生進位,計算結果產生溢出。
再看小數補碼的定義:
上圖中的最高溢出位1去除不要。
上圖則是產生了溢出的情況。兩個小數之和如果超過1,則肯定產生溢出;兩個整數之和如果超過了最大位數(比如兩位十進制能表示的最大數字是99)則產生溢出,上圖中A-B的結果是-138,138超過了7位二進制能表示的最大數字127,因此產生了溢出。
對于小數溢出的檢測,通常采用如下雙符號位:
假設x=-0.110,y=-0.101兩個負數的絕對值都大于0.5,結果應該溢出:
取雙符號位,最后答案:10.101有溢出。
再考慮x=-0.010,y=-0.101兩個負數的絕對值沒有同時大于0.5,結果應該無溢出:
最后答案:11.101無溢出
由以上例子可以看出,當兩個負數的絕對值都大于0.5的時候,其補碼相加時最高數值位不會產生進位,從而導致雙符號不一致,得出溢出的結論;而當兩個負數的絕對值沒有同時大于0.5,其補碼相加時最高數值位會產生進位,得出結果無溢出。這種情形可以通過理論予以證明,我們這里只需要了解一下。
那么,溢出以后如何解決呢?
假設求:-6+(-3)
-6的原碼:1 110-3的原碼:1 011
-6的補碼:1 010-3的補碼:1 101
由于包括符號位是四位,所以結果是0 100,是一個正數,明顯產生了溢出。
為了解決這個問題,將數值位寬度增大為4位,則-6的原碼:1 0110-3的原碼:1 0011
-6的補碼:1 1010-3的補碼:1 1101
最后結果是5位:1 0111。由于這個結果是補碼,再求其原碼得到1 1001,也就是-9,答案是正確的。