《 C 語言的一些“騷操作”及其深層理解》之關于補碼與關于-1
關于補碼
補碼是一個很基礎的概念,但是對于很多人來說,其實有些迷糊,這里對補碼進行一些通俗而深刻的講解。
C語言中的整型類型有兩種,無符號與有符號。無符號比較好理解,如圖2.8所示。

圖2.8 無符號整型的數值表達
只需要將每一個位乘以它的權值,再求和即是其所表達的數值。它所有的位都用來表達數值,因此上圖中類型能表達的范圍為0~255(8個位)。但是如何表達負數,比如-10,這個時候就涉及到補碼了,如圖2.9所示。

圖2.9 有符號整型的數值表達
有符號整型的最高位被定義為符號位,0為正數,1為負數。上圖中前一行等于+76,后一行等于多少?-76?那就錯了。對于負數的數值要按其補碼來計算,如圖2.10所示。

圖2.10 有符號整型負數數值計算方法
為什么要引入補碼的概念,符號位表示符號,其它位直接表示其絕對值,不是更好嗎?這其實是一個數字游戲。我們要知道一個前提:CPU中只有加法器,而沒有減法器。OK,我們看下面的例子。

圖2.11 使用補碼通過加法實現減法操作
可以看到,補碼將符號位也統(tǒng)一到了計算過程中,并且巧妙的使用加法實現了減法操作。這對于簡化CPU中的算術邏輯電路(ALU)具有重要意義。
關于-1
為了說明關于-1的問題,我們先來看一個例子:
signed short a=-1;
if(-1==a)
{
//....
}
這個if條件成立嗎?似乎這是一句廢話。其實不然,它不一定成立。
我們要知道C語言中的判等==運算是一種強匹配,也就是比較的雙方必須每一個位都匹配才被認為相等。上例中,a在內存中的表示是0XFFFF(補碼),但是-1這個常量在內存中的表示在不同的硬件平臺上卻不盡相同,在16位CPU平臺上是0XFFFF,它們是相等的。而在32位CPU平臺上則是0XFFFFFFFF,它們就不相等。所以穩(wěn)妥的辦法是:
signed short a=-1;
if(((signed short)-1)==a)
{
//....
}
我們看到-1的補碼是全F,而且位數與CPU平臺相關。所以-1經常還有另一個妙用,即可以用于判斷硬件平臺的CPU位數,便于提高代碼的可移植性(32位平臺的int(-1)為0XFFFFFFFF,而16位平臺則是0XFFFF)。





