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" 所有这些位一个接一个地翻转。
我是 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" 所有这些位一个接一个地翻转。