关于C中的按位运算符的不同结果

时间:2011-08-09 13:47:54

标签: c bitwise-operators bit-shift

为了实现c中的逻辑右移,我搜索网络并得到以下C代码

int a, b, c;
int x = -100;
a = (unsigned) x >> 2;
b = (0xffffffff & x) >> 2;
c = (0x0 | x ) >> 2;

现在a和b都是逻辑右移结果(1006632960),但c仍然是算术移位结果(-25),有人可以解释为什么吗? THX

3 个答案:

答案 0 :(得分:1)

b = (0xffffffff & x) >> 2;

假设你的整数是32位,那么文字常量0xffffffff的类型是unsigned int,因为它太大而不适合普通int。然后,&介于unsigned intint之间,在这种情况下,无符号类型按定义获胜。因此转移发生在未签名的;因此它从左边移位0位。

c = (0x0 | x ) >> 2;

0x0的类型默认为int,因为它足够小以适应,所以按位或发生在整数上,以及后续移位也是如此。它是实现定义当您正确移位有符号整数时会发生什么,但大多数编译器将产生符号扩展的算术移位。

答案 1 :(得分:1)

(unsigned) x的类型为unsigned int,因此它会进行逻辑移位。

0xffffffff(假设32位int)的类型为unsigned int,因此(0xffffffff & x)也是unsigned int类型,因此它会得到逻辑移位。

0x0的类型为int,因此(0x0|x)的类型为int并获得算术移位(嗯,它取决于实现)。

答案 2 :(得分:0)

所有关于operator >>的操作数类型。如果它是signed - 如果操作数为负,则右移将MSB设置为1。如果操作数为unsigned - 右移后MSB位始终为零。

在第一个表达式中,操作数显式转换为unsigned

在第二个表达式中(0xffffffff & x)我们是无符号的,因为0xffffffff肯定代表一个无符号整数(它是signed的溢出)。

第三个示例0x0中的OTOH是signed(这是整数常量的默认值)。因此,整个操作数(0x0 | x )被视为已签名