怪異的有符號/無符號轉換問題
阿新 • • 發佈:2018-12-27
“(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以考慮符號位
。
回覆 更多評論
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以考慮符號位
。