C++有符號和無符號數

近期調串口通信時,碰到了有符號和無符號數轉換問題,在此小結下:

 

關於“無符號負數”的顯示

     所謂“無符號負數” :這裏是指將負數賦值給無符號類型變量

       負數,無論是賦值給有符號數,還是無符號數,內存中二進制的表示形式是一樣的;顯示成有符號還是無符號,是根據printf的格式化參數來決定的。

%d是按照有符號輸出,%u是按照無符號輸出

u_int32_t a = -100;
u_int32_t b = u_int32_t(-100);

printf("a =  %d !\n", a);
printf("b =  %d !\n", b);
printf("u =  %u !\n", a);
printf("u =  %u !\n", b);


//輸出:
a =  -100 !
b =  -100 !
u =  4294967196 !
u =  4294967196 !

 

       用unsigned定義變量,在C語言運算時有用。譬如位移運算,無符號數右移時,高位補充0,如果是有符號數右移,高位補充的是符號位的值(負數的符號位是1,正數的符號位是0)。

 

關於負數的二進制表示:

      在二進制碼中,爲了區分正負數,採用最高位是符號位的方法來區分,正數的符號位爲0、負數的符號位爲1。剩下的就是這個數的絕對值部分,可以採用原碼、反碼、補碼3種形式來表示絕對值部分。

但對於二進制運算而言,原碼的運算不夠方便,當兩個數相加時,先要判斷這兩個數的符號是否相同,符號不同的話,還要判斷哪一個數的絕對值更大。所以在計算機中,通常都是採用補碼形式。正整數的補碼與原碼形式相同,例如+7的8位二進制補碼是00000111;而負整數的補碼則可以通過下列方式得到:將這個負整數的絕對值求反加1,連同符號位1一起表示就可以了。例如-7的8位二進制補碼:將-7的絕對值7求反加1得1111001,連同符號位1一起就是11111001。

 

關於“無符號 負數”的類型轉換問題:

位運算 丟失符號位:

u_int32_t c = -100;
u_int16_t d_16 = (c & 0xFF00);

printf("c =  %d !\n", c);
printf("d_16 =  %d !\n", d_16);


//輸出:
c =  -100 !
d_16 =  65280 !//負數的低16位和0xFF00與運算,結果賦值給d_16;丟失了符號位,所以很大。

 截斷,丟失符號位:

u_int32_t c = -100;
u_int16_t e_16 = c;
printf("e_16 =  %d !\n", e_16);
//輸出
e_16 =  65436 ! //發生截斷,丟失了符號位,所以很大。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章