C ++左移操作

时间:2019-04-01 14:01:17

标签: c++ bit-shift

这是我的代码

int a=2147483647; 
int b= a<<1;
cout<<"a="<<a<<",  b="<<b;

我得到的输出是- a = 214783647,b = -2

a 的二进制表示形式是

  

0111 1111 1111 1111 1111 1111 1111 1111

通过将其移位1位,它将更改符号位并将LSB替换为0。因此,我认为答案将是-ve,幅度将减去1即 -2147483646 但是它给出的结果为-2。请解释。

3 个答案:

答案 0 :(得分:2)

  

[expr.shift] / 1 E1 << E2的值是E1左移E2位的位置;空出的位为零。 ...如果E1具有带符号的类型且非负值,并且E1 × 2^E2在结果类型的对应的无符号类型中可表示,则将结果转换为结果类型值;否则,行为是不确定的

强调我的。您的程序表现出未定义的行为。


编辑:经过仔细考虑,我不再认为这是未定义的行为。 2147483647*2确实适合unsigned int的{​​{1}},即“相应的无符号类型”。它到int的转换不是不确定的,而仅仅是实现定义的。对于使用二进制补码的实现来定义此转换是完全合理的,以便int仅重新解释位模式,如其他答案所述。

答案 1 :(得分:2)

这是因为您的计算机对符号值使用2补码。 无符号移位值为0xFFFFFFFE,即2补码中的-2,不是-2147483647

移位是用C定义的实现。

顺便说一句,-2147483647在这种CPU上是0x80000001

答案 2 :(得分:1)

好吧,背后还有很长的故事。

因为int是有符号类型,所以它意味着第一位是一个符号,整个系统是两个补码。

所以x = 0b 1111 1111 1111 1111 1111 1111 1111 0111是x = -9 例如x = 0b 1111 1111 1111 1111 1111 1111 1111 1111是x = -1和x = 0b 0000 0000 0000 0000 0000 0000 0000 000000是2

详细了解Two complement