平時工作中有符號數用的少,昨天同事在現場更改代碼需要用到有符號數,發回家里后一下子我也有點暈,又查查資料在IAR和VS中也驗證了下,做好
如下記錄。
C語言中無符號數和有符號數一起比較、運算時,有符號數會隱式轉換到無符號數。
1.無符號數--->有符號數
首先判斷無符號數的最高位是否為1,如果不為1,則有符號數就直接等於無符號數;如果為1,則將無符號數取補碼,得到的數就是有符號數。
本質上就是無符號數在存儲器中的二進制數直接按照有符號數來解析。
現象上也可理解為無符號數先看成有符號數然后取補碼。因為取補碼時符號位不變,正數的補碼就是原碼。
以unsigned char 和 signed char為例子:
定義 unsigned char ui; signed char si;
1.1 將無符號數2轉為有符號數
前提:
ui = 2;
si = ui;
結果:
si = 2;
2的原碼是:0000 0010,最高位不為1,因此si = 0000 0010。
1.2 無符號數130轉為有符號數
前提:
ui = 130;
si = ui;
結果:
si = -126;
130的原碼是:1000 0010,最高位為1,對其取補碼為1111 1110,所以si = 1111 1110 值得到的結果是-126。
2.有符號數--->無符號數
首先判斷有符號數的最高位是否為1,如果不為1,則無符號數就直接等於有符號數;如果有符號數的最高位為1,則將有符號數取補碼,得到的數就是
無符號數。
本質上是有符號數在存儲器中的二進制數直接按照無符號數來解析,
2.1 將有符號數3轉為無符號數
前提:
si = 2;
ui = si;
結果:
ui = 2;
2的原碼是:0000 0010,可知最高位不為1,因此ui = 0000 0010。
2.2 將有符號數-2轉為無符號數
-2的在存儲器中按補碼存放的,二進制表示為:1111 1110,此二進制數按照無符號數解析也就是首位不再表示符號則該值為254。
前提:
si = -2;
ui = si;
結果:
ui = 254;
另外,上述以char舉例,如果換成short或者int等等,要注意只有首位才是符號位。