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

Negative number right shift operator in C++

我是 C++ 的新手,我发现了一些我无法理解的地方。谁能提供一些帮助?

对于以下代码:

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

然后我得到了结果:

我=-3 i >> 1 的计算结果为:-2

不太明白。 由于 3 被编码为(简单来说):

3 : 0000 0011
-3 : 1111 1100

那么经过右移运算后,我们应该有:

-1 : 1111 1110

对吧?为什么我得到-2? (我的 64 位电脑)

感谢您的帮助!

实际上-1 = 0xFFFF = 1111 1111 1111 1111b, -3 = 0xFFFD = 1111 1111 1111 1101b(for 4 byte int ).

所以当你使用右移时,你会得到 1111 1111 1111 1110b-2

你的错误在于假设因为 3 是 00000011,-3 只是通过反转位来表示(所谓的 "one's complement" 表示负数)得到 11111100 .同样,00000001 在取反时变为 11111110。事实上,情况并非如此——相反,您的计算机似乎正在使用几乎通用的 "two's complement" system,其中 -3 表示为 11111101,-2 表示为 11111110,-1 表示为 11111111.

二进制补码系统的一个很好的直觉泵是考虑一系列增量,并注意行为在某种程度上是一致和直观的,无论您是否想象它们发生在位模式本身,有符号的表示形式,或无符号形式。为了简单起见,我们坚持使用 8 位(想象一下“第 9 位”刚刚被丢弃):

bit pattern           interpreted as...
               signed byte    unsigned byte
11111101            -3             253
11111110            -2             254
11111111            -1             255
00000000             0               0  (wrap-around)
00000001             1               1 

当它从 -1 变为 0 时,我几乎可以 "hear" 所有这些位一个接一个地翻转。