1. 程式人生 > >怪異的有符號/無符號轉換問題

怪異的有符號/無符號轉換問題

“(ni-ui)*2被認為是一個有符號的整型,而為什麼(ni-

ui)/2卻被認為是一個無符號整型,是C++的規範,還是編

譯器的問題?”

hi,Jiang. 又在默默耕耘啦~~

請問你根據什麼知道(ni-ui)*2被認為是一個有符號的整

型而(ni-ui)/2卻被認為是一個無符號整型?

如果你是根據printf("%d",XXX)的輸出,那就錯了。因為

printf("%d",XXX)不管XXX是什麼型別都會把XXX當做有符

號數輸出的。

我做了個實驗證明之前那位網友所說,int op unsigned

一定是都轉換為unsignd,是對的。

(寫了段程式碼來證明那位網友的結論:
unsigned int ui = 1;
int ni = 2;

if((ui - ni)<0){
//如果(ui - ni)被轉換為有符號數就會進入這

個分支
printf("should not see me.\n\r");
})

回到你說的問題。那輸出結果到底是什麼?

把你程式碼中的%d換成%x就真相大白了。

printf("%x\n", ni-ui);
printf("%x\n", (ni-ui)*2);
printf("%x\n", (ni-ui)/2);
printf("%x\n", (ni-(int)ui)/2);

輸出結果如下:
ffffffce
ffffff9c
7fffffe7
ffffffe7

那對於你說有問題的那兩句話,
(ni-ui)/2輸出為7fffffe7
(ni-(int)ui)/2)輸出為ffffffe7
為什麼會有這個差異?
請看看彙編程式碼。

在計算(ni-ui)/2時,編譯器使用shr來計算結果。shr是

邏輯右移,右移的同時高位填0,所以得到7fffffe7。
在計算(ni-(int)ui)/2時,編譯器使用sar來計算結果。

sar是算術右移,右移的同時保留符號位,所以得到

ffffffe7。

那為什麼(ni-ui)/2採用shr而(ni-(int)ui)/2採用sar?
我想就像前面那位網友說的,(ni-ui)被轉換為無符號數

,所以編譯器採用shr忽略符號位;而(ni-(int)ui)被強

制轉換為有符號數,所以編譯器採用了sar以考慮符號位


  
回覆
  更多評論