![](/img/trans.png)
[英]Why does shift right in practice shifts left (and viceversa) in Neon and SSE?
[英]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。
因此在原始示例中, b
, d
, f
和h
都將獲得0值, a
和c
都獲得8
值:直到此處才有完美定義的行為。
但是e
和g
將接收無符號值0x80000000
,所以如果你將它影響到unsigned int變量就可以了,但你使用的是帶符號的32位整數。 所以你得到一個積分轉換 :4.7積分轉換[conv.integral]§3
如果目標類型已簽名,則該值如果可以在目標類型中表示,則不會更改; 否則,該值是實現定義的。
無符號0x80000000在有符號的64位整數中無法表示,因此結果是為e
和g
定義的實現 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.