在計算機系統中,數值一律用補碼來表示和存儲。原因在於,使用補碼,可以將符號位和數值域統一處理;
在理解補碼的之前,得先了解另外一個概念:
補數;以十進制為例,不考慮負數,1位十進制數能表示的最大的數是9,最小是0。由於進位的原因,0-1=0+9會得到9。9是-1以10為模的補數,目前來看,這東西根本沒啥用!!沒錯,對人來說確實沒啥用,但對計算機來說不一樣,在計算機中所有的信息都是以二進制來表示的,所有的信息都用0和1表示,專門留出1個位表示正負號,不但浪費資源,做計算時也不方便。所以,天才的計算機科學家(具體是誰不知道,一說是馮諾依曼)利用補碼,不但能正確的表示負數,而且還將加減乘除均運算都轉換成簡單的加法運算,現在我們來看看他/她是怎么做到的吧:
以4位二進制做例子,先把能表示的數字放到一個表盤上,外圈為二進制,內圈為10進制:

根據上述補數的原理可知,在上面這個表盤中如果有一個數x,那么:
x - 1 = x + (-1) +16 = x +15
x - 2 = x + (-2) +16 = x +14
......
x - 7 = x + (-7) +16 = x + 9
x - 8 = x + (-8) +16 = x + 8
x - 9 = x + (-9) +16 = x + 7
x - 10 = x + (-10) +16 = x +6
......
x - 15 = x + (-15) +16 = x + 1
x - 8 = x + (-8) +16 = x + 8
x - 9 = x + (-9) +16 = x + 7
x - 10 = x + (-10) +16 = x +6
......
x - 15 = x + (-15) +16 = x + 1
是不是有靈感了,不是不能表示負數嗎?那咱們用15表示-1,用14表示-2,……,用8表示-8,所有的加法(減法、乘法、除法運算均可以轉換為加法)運算結果在上述表盤上的結果都不會收到影響!!這樣在上述表盤就可以表示-8~+7之間所有的整數。用來表示-1的二進制碼就是-1的補碼(1111)。
我們把結果畫到圖上,結果如下:

注意所有的運算只有在上述表盤中才成立,上述的結論脫離了對應的表盤就是不成立。同時我們只是用15表示了-1,因為這樣替換不影響計算結果,並不是說15就等於-1,這里面有區別。
是不是覺得萬事大吉了?然而並沒有!!!
在上述表盤中試試計算下6+7 或者-7+(-8),是不是覺得有點失望,完全不是想要的結果!這就是溢出,因為上述表盤只能表示-8~+7之間的數,如果計算結果超出這個范圍就會出現錯誤,
如何檢測整型相加溢出。
還有一個重要問題:在學習補碼的時候,很多教材、文章說求補碼的過程先求反碼、再求補碼,給人的感覺是補碼由於反碼推導出來的,其實不是,這是誤導!!!如果按照先求反碼,再求補碼的過程來理解補碼,就會感到迷茫。我在這個坑里待了好久才跳出來。還好有一篇文章提醒了我,但是現在找不着出處了,原作者如果看到,請提醒我加鏈接。