C ++中的负数右移运算符

时间:2019-01-26 19:22:15

标签: c++ bit-shift

我是C ++的新手,我发现一些我无法理解的东西。有人可以提供帮助吗?

对于以下代码:

int i = -3;
printf("i=%d\n",i);
i = i >> 1:
printf("i >> 1 evaluates to: %d\n", i);

然后我得到了结果:

i = -3 i >> 1计算为:-2

我不太明白。 由于3被编码为(让我们简单点):

3 : 0000 0011
-3 : 1111 1100

然后右移操作后,我们应该有:

-1 : 1111 1110

对吗?为什么我得到-2? (我的PC为64位)

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

实际上-1 = 0xFFFF = 1111 1111 1111 1111b-3 = 0xFFFD = 1111 1111 1111 1101b(用于4字节int)。

因此,当您使用右移时,会得到1111 1111 1111 1110b的{​​{1}}

答案 1 :(得分:1)

您的错误在于假设因为3是00000011,所以-3的表示仅是通过反转位(负数的“一个补码”表示)来获得11111100。而且,00000001取反时也变成11111110。实际上并非如此-相反,您的计算机似乎正在使用几乎通用的"two's complement" system,其中-3表示为11111101,-2表示11111110,-1表示{{ 1}}。

一个用于二进制补码系统的不错的直觉泵是考虑一系列增量,并且要注意,无论您是否想象它们发生在位模式本身中,在有符号表示中,其行为在某种程度上都是一致且直观的,或未签名。为了简单起见,我们坚持使用8位(想象一下“ 9th bit”就被丢弃了):

11111111

当它从-1变为0时,我几乎可以“听到”所有这些位依次翻转。