《 C 語言的一些“騷操作”及其深層理解》之關(guān)于補碼與關(guān)于-1
關(guān)于補碼
補碼是一個很基礎(chǔ)的概念,但是對于很多人來說,其實有些迷糊,這里對補碼進行一些通俗而深刻的講解。
C語言中的整型類型有兩種,無符號與有符號。無符號比較好理解,如圖2.8所示。
圖2.8 無符號整型的數(shù)值表達
只需要將每一個位乘以它的權(quán)值,再求和即是其所表達的數(shù)值。它所有的位都用來表達數(shù)值,因此上圖中類型能表達的范圍為0~255(8個位)。但是如何表達負數(shù),比如-10,這個時候就涉及到補碼了,如圖2.9所示。
圖2.9 有符號整型的數(shù)值表達
有符號整型的最高位被定義為符號位,0為正數(shù),1為負數(shù)。上圖中前一行等于+76,后一行等于多少?-76?那就錯了。對于負數(shù)的數(shù)值要按其補碼來計算,如圖2.10所示。
圖2.10 有符號整型負數(shù)數(shù)值計算方法
為什么要引入補碼的概念,符號位表示符號,其它位直接表示其絕對值,不是更好嗎?這其實是一個數(shù)字游戲。我們要知道一個前提:CPU中只有加法器,而沒有減法器。OK,我們看下面的例子。
圖2.11 使用補碼通過加法實現(xiàn)減法操作
可以看到,補碼將符號位也統(tǒng)一到了計算過程中,并且巧妙的使用加法實現(xiàn)了減法操作。這對于簡化CPU中的算術(shù)邏輯電路(ALU)具有重要意義。
關(guān)于-1
為了說明關(guān)于-1的問題,我們先來看一個例子:
signed short a=-1;
if(-1==a)
{
//....
}
這個if條件成立嗎?似乎這是一句廢話。其實不然,它不一定成立。
我們要知道C語言中的判等==運算是一種強匹配,也就是比較的雙方必須每一個位都匹配才被認為相等。上例中,a在內(nèi)存中的表示是0XFFFF(補碼),但是-1這個常量在內(nèi)存中的表示在不同的硬件平臺上卻不盡相同,在16位CPU平臺上是0XFFFF,它們是相等的。而在32位CPU平臺上則是0XFFFFFFFF,它們就不相等。所以穩(wěn)妥的辦法是:
signed short a=-1;
if(((signed short)-1)==a)
{
//....
}
我們看到-1的補碼是全F,而且位數(shù)與CPU平臺相關(guān)。所以-1經(jīng)常還有另一個妙用,即可以用于判斷硬件平臺的CPU位數(shù),便于提高代碼的可移植性(32位平臺的int(-1)為0XFFFFFFFF,而16位平臺則是0XFFFF)。