了解 C++14 中有符号类型的按位左移

Understanding bitwise left shift on signed types in C++14

根据cppreference

For signed a, the value of a << b is a * 2^b if it is representable [in the unsigned version of the (since C++14)] return type [(which is then converted to signed: this makes it legal to create INT_MIN as 1 << 31) (since C++14)], otherwise the behavior is undefined.

我不太明白这个规范。 如果它在 return 类型的无符号版本中是可表示的 究竟是什么意思?它仅适用于有符号值非负的情况吗? INT_MIN << 1-1 << 31 定义明确吗?

如果我们查看 C++14 标准的源代码,我们会发现以下内容(突出显示有关无符号类型的部分):

The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 × 2E2 , reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1 × 2E2 is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.

对于std::numeric_limits<int>::digits为31的平台,执行1 << 31是合法的。 unsigned int 中的结果值为 0x800000002147483648。但是,该数字超出了此类平台的 int 的有效值范围。然而,当被视为二进制补码表示时,该位模式 int 等于 -2147483648,这与此类平台的 INT_MIN 相同。

如果你使用

int a = 2 << 31;

您调用了未定义的行为,因为 2 * 231 在该平台中无法表示为 unsigned int

Are INT_MIN << 1 and -1 << 31 well-defined?

不,他们不是。按位左移负数是未定义的行为。请注意在上面突出显示的文本中使用 非负值