[英]Right shift and signed integer
在我的編譯器上,以下偽代碼(用二進制替換的值):
sint32 word = (10000000 00000000 00000000 00000000);
word >>= 16;
使用如下所示的位域生成一個word
:
(11111111 11111111 10000000 00000000)
我的問題是,我可以依賴所有平台和C ++編譯器的這種行為嗎?
從以下鏈接:
INT34-C。 不要將表達式移位負數位或大於或等於操作數中存在的位數
不合規的代碼示例(右移)
E1 >> E2
的結果是E1
右移E2
位的位置。 如果E1
具有無符號類型或者E1
具有有符號類型和非負值,則結果的值是E1 / 2 E2的商的整數部分。 如果E1
具有帶符號類型和負值,則結果值是實現定義的,可以是算術(帶符號)移位:
或邏輯(無符號)轉變:
這個不合規的代碼示例無法測試右操作數是否大於或等於提升的左操作數的寬度,從而允許未定義的行為。
unsigned int ui1;
unsigned int ui2;
unsigned int uresult;
/* Initialize ui1 and ui2 */
uresult = ui1 >> ui2;
假設右移是實現為算術(帶符號)移位還是邏輯(無符號)移位也可能導致漏洞。 見建議INT13-C。 僅在無符號操作數上使用按位運算符 。
不,你不能依賴這種行為。 負數量的右移(我假設你的例子正在處理)是實現定義的。
在C ++中,沒有。 它取決於實現和/或平台。
在其他一些語言中,是的。 例如,在Java中,>>運算符被精確定義為始終使用最左邊的位填充(從而保留符號)。 >>>運算符使用0填充。 因此,如果您需要可靠的行為,一種可能的選擇是更改為其他語言。 (雖然很明顯,根據您的具體情況,這可能不是一種選擇。)
AFAIK整數可以用c ++表示為符號幅度,在這種情況下,符號擴展將填充0。 所以你不能依賴這個。
從最新的C ++ 20草案 :
有符號整數類型的右移是算術右移,它執行符號擴展。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.