为什么-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 ,它必须是无符号的。