我正在尝试进行测试,以判断我的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/

10-09 13:22