为什么-1 >> 1和0xFFFFFFFF >> 1产生不同的结果?
我试图通过右移hexFFFFFFFF
来判断我的PC是执行算术还是逻辑右移。
我知道整数-1
以hex读取为FFFFFFFF
,因为它是1
的二进制补码。 右移-1
乘以FFFFFFFF
并显示PC执行算术右移。
但是,如果我只输入0xFFFFFFFF >> 1
,则会产生7FFFFFFF
并显示PC执行逻辑右移。 为什么会这样? 请参阅下面生成结果的代码:
#include #include int main ( int argc, char *argv[] ) { printf ( "%x >> 1 = %x\n", -1, -1 >> 1 ); printf ( "%x >> 1 = %x\n", 0xffffffff, 0xffffffff >> 1 ); return EXIT_SUCCESS; }
该计划的输出是:
ffffffff >> 1 = ffffffff ffffffff >> 1 = 7fffffff
这不是一个假设。 你认为0xffffffff
是什么类型的 ? 根据C标准, 6.4.4.1整数常量 , hex常量(以0x
)的表达式类型是以下第一个可以适用地保存表示值的值:
int unsigned int long int unsigned long int long long int unsigned long long int
在您的平台上,0xFFFFFFFF不能表示为int
因为int
是32位且只有31位表示signed int
数量(标准规定一位保留用于符号)。 因此使用下一个类型unsigned int
。 因此,在移位操作中不存在符号位,因此是逻辑而不是算术。
我的结论可能并不明显,你的平台上有32位。 事实上,我不能做出这样的假设,如果不是第一行,算术右移-1
的值。 转换为%x
转换结果为0xFFFFFFFF
。 如果int
是本机64位,则应转储0xFFFFFFFFFFFFFFFF
。 在没有该先验知识的情况下,不能假设单个类型的0xFFFFFFFF
结论,因为它可以表示为宽度为64位(63 + 1)且值为0x00000000FFFFFFFF
的标准有符号int
。 由此产生的移位将产生您现在看到的相同输出,从而引入上述假设的替代方案。
你的主要问题是: 0xffffffff
是无符号的吗?
从C11§6.4.4.1整数常量
整数常量的类型是相应列表中可以表示其值的第一个。
第一个printf
行的输出表明int
在您的计算机上是32位。 因此它不能代表0xffffffff
,它必须是无符号的。