为什么-1 >> 1和0xFFFFFFFF >> 1产生不同的结果?

vxs*_*122 9 c bit-shift bitwise-operators

我正在尝试进行测试,以判断我的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;
}
Run Code Online (Sandbox Code Playgroud)

该计划的输出是:

ffffffff >> 1 = ffffffff
ffffffff >> 1 = 7fffffff
Run Code Online (Sandbox Code Playgroud)

Who*_*aig 8

这不是一个假设.你觉得是什么类型的0xffffffff?根据C标准,6.4.4.1整数常量,十六进制常量(前面带有)的表达式的类型是以下第一个可以适用地保存表示值的值:0x

int
unsigned int
long int
unsigned long int
long long int
unsigned long long int
Run Code Online (Sandbox Code Playgroud)

在您的平台上,0xFFFFFFFF不能表示为int因为int32位且只有31位表示数量signed int(标准规定一位保留用于符号).unsigned int因此使用下一种类型.因此,在移位操作中不存在符号位,因此是逻辑而不是算术.

我的结论可能并不明显int,你的平台上有32位.事实上,我不能做出这样的假设:如果不是第一行,那么算术右移会改变它的价值-1.这种转变的结果,倾倒为%x,是0xFFFFFFFF.有int过原生64位认为应该转储0xFFFFFFFFFFFFFFFF代替.如果没有先验知识,则不能0xFFFFFFFF假设单一类型的结论,因为它可以表示为int具有值的宽度64位(63 + 1)的标准0x00000000FFFFFFFF.由此产生的移位将产生您现在看到的相同输出,从而引入上述假设的替代方案.


Yu *_*Hao 6

你的主要问题是:0xffffffff未签名?

从C11§6.4.4.1整数常量

整数常量的类型是相应列表中可以表示其值的第一个.

在此输入图像描述

第一printf行的输出表明int您的计算机上是32位.因此它不能代表0xffffffff,它必须是无符号的.