C ++左移操作

问题描述 投票:0回答:3

这是我的代码

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位,它将改变符号位并用0替换LSB。因此,我认为答案将是-ve和幅度将减1,即-2147483646但它给出的结果为-2。请解释。

c++ bit-shift
3个回答
2
投票

这是因为您的计算机使用2补码表示签名值。无符号移位值是0xFFFFFFFE,它是2补充中的-2,而不是-2147483647

移位是在C中定义的实现。

顺便说一下,-2147483647就是这样的CPU上的0x80000001


2
投票

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

强调我的。您的程序显示未定义的行为。


编辑:经过仔细考虑,我不再认为它是未定义的行为。 2147483647*2确实适合unsigned intint的“相应的无符号类型”。它转换为int并不是未定义的,而只是实现定义的。使用二进制补码定义这种转换的实现是完全合理的,因此2147483647*2 == -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 0010是2

了解有关Two complement的更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.