移位运算符如何影响无符号数

时间:2018-05-01 05:55:36

标签: c++ c bit-manipulation

假设x是unsigned int

然后x << n等于 x * 2 n

我知道签名整数是真的。

x * 15 等于x << 4 - x

1 个答案:

答案 0 :(得分:1)

这个答案是针对C语言的。对于这个特定的问题,C ++规范似乎存在微妙的差异。

如果x未签名如果n >= 0且小于x类型中的值位数,则x << n确实如此与将x乘以2的n次幂相同。

如果此计算溢出,结果将以x加1的最大值模数减去。

如果x已签名,则必须为非负数,结果不得溢出,否则您将获得未定义的行为。 32位体系结构上未定义行为的常见情况是:

unsigned x = 1 << 31;   /* undefined behavior: 1 is signed, 31 is too large */

正确的版本是:

unsigned x = 1U << 31;   /* correct on 32 bit architectures */

顺便提一下,从C ++ 14开始,C ++标准对这种情况有一个特定的规定:

a << b的值是2 b 的次数,如果它在返回类型的无符号版本中可表示(然后转换为signed:这使其合法将INT_MIN创建为1 << 31),否则行为未定义。

关于您的第二个问题,x * 15是否等于x << 4 - x

答案是否定的,因为x << 4 - x被解析为x << (4 - x)

如果您将表达式括起来,那么确实x * 15 == (x << 4) - x

但请注意,签名值不正确,因为中间结果x << 4可能会因x的大x * 15的大值而溢出。