根据cppreference,
对于已签名的
a
,a << b
的值为a * 2^b
(如果是) 可表示[在(从C ++ 14开始)的无符号版本]返回 type [(然后转换为signed:这使得它合法 创建INT_MIN
为1 << 31
)(因为C ++ 14)],否则就是行为 未定义。
我不太明白这个规范。如果在返回类型的无符号版本中可表示,那么它究竟意味着什么?它是否仅适用于签名值为非负值的情况? INT_MIN << 1
和-1 << 31
定义明确吗?
答案 0 :(得分:1)
如果我们转到C ++ 14标准源代码,这就是我们发现的内容(突出显示有关无符号类型的部分):
E1 << E2
的值为E1
左移E2
位位置;空位是零填充的。如果E1
具有无符号类型,则结果的值为E1 × 2
E2
,比结果类型中可表示的最大值减少一个模数。否则,如果E1
具有签名类型和非负值,则E1 × 2
E2
可在结果类型的相应无符号类型中表示,然后转换为结果类型的值是结果值;否则,行为未定义。
对于std::numeric_limits<int>::digits
为31的平台,执行1 << 31
是合法的。 unsigned int
中的结果值为0x80000000
或2147483648
。但是,对于这样的平台,该数字超出了int
的有效值范围。但是,当被视为双补码表示int
时,该位模式等于-2147483648
,这与此类平台的INT_MIN
相同。
如果您使用
int a = 2 << 31;
您调用未定义的行为,因为2 * 2
31
在该平台中无法表示为unsigned int
。
是INT_MIN&lt;&lt; 1和-1&lt;&lt; 31定义明确?
不,他们不是。按位左移位负数是未定义的行为。请注意在上面突出显示的文本中使用非负值。