簡體   English   中英

布爾值左移和右移

[英]Left shifts and right shifts on boolean

我試圖理解exaclty積分推廣如何與算術移位運算符一起工作。 特別是,我想知道, a, b, c, d, e, f, g, h哪些值是根據C ++ 14標准精確定義的,哪些可以依賴於平台/硬件/編譯器(假設sizeof(int) == 4 )。

int a = true << 3;
int b = true >> 3;

int c = true << 3U;
int d = true >> 3U;

int e = true << 31;
int f = true >> 31;

int g = true << 31U;
int h = true >> 31U;

來自[expr.shift]:

結果的類型是提升的左操作數的類型。 如果右操作數為負數,或者大於或等於提升左操作數的位長度,則行為未定義。

無論右側是什么,移動bool的結果類型總是int 我們永遠不會偏移至少32或負數,所以我們在所有帳戶上都可以。

對於左移(E1 << E2):

否則,如果E1具有有符號類型和非負值,並且E1×2 E2在結果類型的相應無符號類型中可表示,則轉換為結果類型的該值是結果值; 否則,行為未定義。

1×2 31可以用unsigned int表示,這是我們正在做的最大的左移,所以我們在所有帳戶上都可以。

對於右移(E1 >> E2):

如果E1具有帶符號類型和負值,則結果值是實現定義的。

E1永遠不會消極,所以我們也可以! 任何地方都沒有未定義或實現定義的行為。

以下主要是對巴里答案的補充,這清楚地解釋了左右移位的規則。

至少對於C ++ 11,bool的整體提升為0表示false ,1表示true :4.5 Integral promotion [conv.prom]§6

bool類型的prvalue可以轉換為int類型的prvalue,false變為零,true變為1。

因此在原始示例中, bdfh都將獲得0值, ac都獲得8值:直到此處才有完美定義的行為。

但是eg將接收無符號值0x80000000 ,所以如果你將它影響到unsigned int變量就可以了,但你使用的是帶符號的32位整數。 所以你得到一個積分轉換 :4.7積分轉換[conv.integral]§3

如果目標類型已簽名,則該值如果可以在目標類型中表示,則不會更改; 否則,該值是實現定義的。

無符號0x80000000在有符號的64位整數中無法表示,因此結果是為eg 定義實現

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM