为了实现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
答案 0 :(得分:1)
b = (0xffffffff & x) >> 2;
假设你的整数是32位,那么文字常量0xffffffff
的类型是unsigned int
,因为它太大而不适合普通int
。然后,&
介于unsigned int
和int
之间,在这种情况下,无符号类型按定义获胜。因此转移发生在未签名的;因此它从左边移位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 )
被视为已签名