首页 > 解决方案 > C++中的负数右移运算符

问题描述

我是 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?(我的电脑是 64 位的)

谢谢你的帮助!

标签: c++bit-shift

解决方案


您的错误在于假设因为 3 是00000011,所以 -3 仅通过反转位(负数的所谓“一个补码”表示)来表示 get 11111100。当被否定时,这同样00000001会变成。11111110事实上并非如此——相反,您的计算机似乎正在使用几乎通用的“二进制补码”系统,其中 -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 时,我几乎可以“听到”所有这些位一个接一个地翻转。


推荐阅读