2012-08-30 48 views
0

我正在学习C语言。我有这样的代码,更可在需要时提供:当我用GDB和打印/x mask1>>移位操作符不按预期方式工作

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

,我得到0x0,这是正确的。 那么为什么:

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

print 0xffffffff 

应该不是被打印0x0000000f,因为我左移28位?

它与我在64位机器上占用的位数有关吗? 我看着this,但它并没有完全回答。

+3

将'mask1'设为'unsigned int',您将体验到您期望的行为(即逻辑右移)。 – oldrinb

+0

@veer谢谢。那样做了。 – Clara

+0

阅读实用的程序员,这本书有一个标题为“选择不坏”的部分。它描述了你遇到的问题。 – Incognito

回答

5

对负整数的右移行为是实现定义的。一种常见的行为是算术移位,它符号扩展。这样做的好处是,右移也可以被二的幂(四舍五入为负无穷)划分,就像正数一样。

0

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

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

如果你声明掩码为unsigned int,那么它可能会做你想做的。

1

您正在转移。这是正确的:>>,这是遗漏的:<<

通常情况下,当你转向一个(签字)整数权,你认为可以改变但不是标志:这就是丹尼尔指符号扩展。这不是标准所要求的,并非所有平台都这样做。

实际上,在使用二进制补码的系统中,这意味着负值将会使新的最高位填充1,正值和0

例如,一个8位的二进制补码系统上:

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

将负整数右移的结果是实现定义的。不保证保持负面。 – Nemo

+0

确实,即将编辑 – Useless

0

是的,作为@veer指出,与int你在做一个算术右移这对于以2的幂将有符号数(在二进制补码表示)是伟大的:

Right arithmetic shift

通过改变类型unsigned int它将成为一个右键按位移位这是伟大的以2的幂除以无符号数(这是您的方案):

Right logical shift

一些优秀的解释是Wikipedia Bitwise operation