負數取反,單目運算“-”的運算


首先看代碼:

int main(){
   int i=-2147483648;
   return printf("%d,%d,%d,%d",~i,-i,1-i,-1-i);
}

輸出結果為:

2147483647,-2147483648,-2147483647,2147483647

這里就涉及到對負數取反,單目運算符“-”的理解,在int占4個字節,大小范圍為-2147483648~2147483648,最高位代表符號位,所以第32位為1,這里就需要理解計算機中負數的表示形式:

計算機中的數字都是以補碼的形式存放!

正數的原碼、反碼、補碼都相同

5在計算機中原碼、反碼、補碼均為:00000000 00000000 00000000 00000101

負數的反碼為對該數的原碼除符號位外各位取反,補碼為其反碼加1:

-5原碼為:10000000 00000000 00000000 00000101

反碼為:11111111 11111111 11111111 11111010

補碼為:11111111 11111111 11111111 11111011

所以-5在計算機中存儲形式為11111111 11111111 11111111 11111011轉換為十六進制為:0xFFFFFFFB

但是-2147483648比較特殊!

-2147483648原碼為:10000000  00000000  00000000  00000000 (表示-0)

反碼為:11111111 11111111 11111111 11111111

補碼為:00000000  00000000  00000000  00000000

 +0的原碼、補碼、反碼均為00000000  00000000  00000000  00000000

如果用-2147483648用補碼00000000  00000000  00000000  00000000來表示則和0的補碼一樣,不能區分開;

所以計算機規定用10000000 00000000 00000000 00000000來表示-2147483648的補碼,

32位最小負整數的補碼為10000000 00000000 00000000 00000000

計算機中-2147483648取反為:01111111 11111111 11111111 11111111,此為存儲正數的補碼,換算原碼得到數為2147483647

單目運算符“-”為取負,-2147483648取負為2147483648,顯然超過int類型范圍(-2147483648~2147483647),剛好超過一個就變為-2147483648,所以其對應的補碼仍為10000000 00000000 00000000 00000000,

對應補碼理解就是-x=~x+1;即補碼取反加1,10000000 00000000 00000000 00000000取反加1后任然為10000000 00000000 00000000 00000000,對應數為-2147483648

1-i為(-i)+1,對應補碼為:

10000000 00000000 00000000 00000000+00000000 00000000 00000000 00000001=10000000 00000000 00000000 00000001

轉換為十進制為:- 2147483647

-1-i為(-i)+(-1),對應補碼為:

10000000 00000000 00000000 00000000+11111111 11111111 11111111 11111111=01111111 11111111 11111111 11111111

轉換為十進制為: 2147483647

其實也可以從十進制理解:-2147483648-1=-2147483649,超過范圍后變為2147483647


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM