![](/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.