>>班次经营者没有按预期工作

时间:2012-08-30 21:56:27

标签: c gdb

我正在学习C语言。我有这个代码,如果需要可以提供更多代码:

int result = 0;
int mask1 = 0x0000ffff;
mask1 = mask1 >> 28;

当我使用gdb并打印/x mask1时,我得到0x0,这是正确的。 那为什么:

int result = 0;
int mask1 = 0xffffffff;
mask1 = mask1 >> 28;

print 0xffffffff

不应该打印0x0000000f,因为我要移位28位?

是否与我的64位机器上占用的int位数有关? 我看了this,但它并没有完全回答所有问题。

5 个答案:

答案 0 :(得分:5)

负整数右移的行为是实现定义的。一种常见的行为是算术移位,它进行符号扩展。这样做的好处是右移也可以除以2的幂(舍入到负无穷大),就像正数一样。

答案 1 :(得分:1)

您正在正确。这是正确的:>>,现在留下:<<

通常,当你正确地移动一个(带符号)整数时,你会假设你正在改变而不是符号:这就是Daniel的意思通过签名扩展。标准并不要求它,并非所有平台都这样做。

实际上,在使用二进制补码的系统上,这意味着负值会使新的顶部位填充1,而正值会填充0

例如,在8位2s补码系统上:

before          after >> 1
11111110 = -2   11111111 = -1 (so new top bit was 1)
00000010 = +2   00000001 = +1 (so new top bit was 0)

答案 2 :(得分:0)

如果您将0xffffffff打印为整数,您将意识到它被视为-1。

Bitshift与负数的工作方式不同,因为它用1填充最高位。所以基本上,0xffffffff&gt;&gt; 1 == 0xffffffff。

如果您将面具声明为unsigned int,那么它可能会执行您想要的操作。

答案 3 :(得分:0)

负整数的按位右移是实现定义的。

以下是gcc的作用:

  

对有符号整数进行一些按位运算的结果(C90 6.3,C99 6.5)。

     

签名`&gt;&gt;'通过符号扩展对负数进行处理。

http://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html

答案 4 :(得分:0)

是的,正如@veer指出的那样,int你正在做一个正确的算术移位,这对于将有符号数除以2的幂(以二进制补码表示)是很好的:

Right arithmetic shift

通过将类型更改为unsigned int,它将成为右向位移,非常适合将无符号数除以2的幂(这是您的方案):

Right logical shift

关于Wikipedia Bitwise operation的一些很好的解释。