我正在尝试进行测试,以判断我的PC是通过将十六进制FFFFFFFF
右移还是1
来执行算术还是逻辑右移。
我知道整数-1
读为十六进制的FFFFFFFF
,因为它是1
的二进制补码。将-1
右移1
会得到FFFFFFFF
,并显示PC执行的算术右移。
但是,如果我只键入0xFFFFFFFF >> 1
,则会生成7FFFFFFF
,并表明PC而是执行了逻辑右移。为什么会这样呢?请参阅下面产生结果的代码:
#include <stdlib.h>
#include <stdio.h>
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整数常量,十六进制常量(以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
。因此,不存在随着移位操作而扩展的符号位,因此这是逻辑而不是算术运算。我如何断定
int
在您的平台上是32位可能并不明显。的确,如果不是第一行,我就无法做出这样的假设,即算术右移-1
的值。该转换的结果转为%x
,转储为0xFFFFFFFF
。如果int
是 native 64位,则应该转储0xFFFFFFFFFFFFFFFF
。在没有该先验知识的情况下,无法假设0xFFFFFFFF
的单一类型结论,因为它可以很好地表示为值int
的宽度为64位(63 + 1)的标准带符号0x00000000FFFFFFFF
。产生的移位将产生与您现在看到的相同的输出,从而引入了上面假定的替代方法。关于c - 为什么-1 >> 1和0xFFFFFFFF >> 1会产生不同的结果?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24666567/