【轉】有符號數與無符號數


有、無符號數之間的運算

有符號數與無符號數之間的運算,編譯器會進行隱式類型轉換。

請看如下代碼:

#include <stdio.h> int main(void) { unsigned int a = 6; int b = -20; if ( a+b > 6 ) printf("a+b大於6\n"); else printf("a+b小於6\n"); return 0; }

程序輸出結果為:

a+b大於6

原因是因為編譯器會將有符號數b轉換成為一個無符號數,即此處a+b等價於a+(unsigned int)b

該程序運行在32bit環境下,b的值為0xFFFFFFFF-20+1 = 4294967276,即a+b將遠遠大於6。

C 語言按照一定的規則來進行此類運算的轉換,這種規則稱為正常算術轉換,轉換的順序為:

double>float>unsigned long>long>unsigned int>int

即操作數類型排在后面的與操作數類型排在前面的進行運算時,排在后面的類型將隱式轉換為排在前面的類型。

有、無符號數轉化為更大類型

請看如下代碼:

#include <stdio.h> int main(void) { //情況一 signed char c1 = 0xff; unsigned char c2 = 0xff; int a1,a2; a1 = (int)c1; a2 = (int)c2; printf("a1=%d(%#.8X),a2=%d(%#.8X)\n",a1,a1,a2,a2); //情況二 signed char c3 = 0x80; unsigned char c4 = 0x80; int a3,a4; a3 = (int)c3; a4 = (int)c4; printf("a3=%d(%#.8X),a4=%d(%#.8X)\n",a3,a3,a4,a4); //情況三 signed char c5 = 0x7f; unsigned char c6 = 0x7f; int a5,a6; a5 = (int)c5; a6 = (int)c6; printf("a5=%d(%#.8X),a6=%d(%#.8X)\n",a5,a5,a6,a6); return 0; }

程序輸出結果為:

a1=-1(0XFFFFFFFF),a2=255(0X000000FF) a3=-128(0XFFFFFF80),a4=128(0X00000080) a5=127(0X0000007F),a6=127(0X0000007F)

可見:

(1)將無符號數轉換為更大的數據類型時, 只需簡單地在開頭添加0至所需位數,這種運算稱為0擴展。

(2)將有符號數轉換為更大的數據類型需要執行符號擴展,規則是將符號位擴展至所需的位數,即符號位為0時在開頭添加0至所需位數,符號位為1時在開頭添加1至所需位數。

此外,還需注意,對於一個signed char類型數據,0xff代表的是-1,因為整數在內存中是以補碼的形式存儲的。

正數的原碼、反碼、補碼都相等。負數的反碼是將原碼中除符號位以外的所有位(數值位)取反,也就是 0 變成 1,1 變成 0;負數的補碼是其反碼加 1。

此處,對於一個signed char類型數據,-1的原碼為1000 0001,反碼為1111 1110,所以補碼為1111 1111。

signed char的負數對應表為(圖片來源於網絡):

其中,-128最為特殊,需要特別記住,其不遵循傳統的由補碼計算原碼的方法。

以上就是關於有符號數與無符號數的兩點總結:(1)有符號數與無符號數之間的運算,編譯器會進行隱式類型轉換。(2)有符號數、無符號數轉換為更大的數據類型。

本文參與騰訊雲自媒體分享計划,歡迎正在閱讀的你也加入,一


免責聲明!

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



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