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

标签 c++ bit-manipulation language-lawyer c++14 bit-shift

根据 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.

我不太明白这个规范。 如果它在返回类型的无符号版本中是可表示的究竟意味着什么?它仅适用于有符号值非负的情况吗?是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 * 2 起您调用未定义的行为 31 不能表示为 unsigned int在那个平台上。

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

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

关于c++ - 了解 C++14 中有符号类型的按位左移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35110405/

相关文章:

assembly - 为什么汇编 POPCNTQ 基准测试会比使用整数技巧的 native Go 函数慢?

c++ - vector<bool> 是否违反容器要求?

c++ - 在 std::map 上使用 Lambda 函数

c++ - 使用 Boost::tokenizer 的两个相同程序,但有两个不同的输出

c++ - 为什么在使用 try_lock() 时需要显式比较?

java - 像 C#/Java 这样的高级语言屏蔽移位计数操作数的原因是什么?

c++ - 将位图保存到从中加载的同一文件

java - 反转二进制字符串java的位

c++ - "a subsequent condition of that statement"的标准是什么意思?

c++ - 引用类模板参数和 constexpr 类成员的转换运算符