我试着做一个测试,看看我的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
发布于 2014-07-10 02:39:12
这不是一个假设。你认为0xffffffff
是哪种类型的?根据C标准,即6.4.4.1整数常量,十六进制常数的表达式类型(在0x
之前)是第一个可应用程序保持表示值的表达式:
int
unsigned int
long int
unsigned long int
long long int
unsigned long long int
在您的平台上,0xFFFFFF不能表示为int
,因为int
是32位,在signed int
中只有31位表示量(标准规定一位保留给符号)。因此,使用下一个类型,unsigned int
。因此,没有符号位可以用移位操作进行扩展,因此移位操作是逻辑的,而不是算术的。
我如何得出int
是您平台上32位的结论可能还不太清楚。事实上,如果没有第一行,我就无法做出这样的假设,因为第一行的算术--右移--改变了-1
的值。这一转变的结果--被抛弃为%x
--是0xFFFFFFFF
。如果int
是本地的64位,那么应该转储0xFFFFFFFFFFFFFFFF
。如果没有这些先验知识,就不能假定0xFFFFFFFF
的任何一种类型的结论,因为它很可能可以表示为具有值0x00000000FFFFFFFF
的标准带符号64位的int
(63+1)。由此产生的转换将产生与您现在看到的输出相同的结果,从而引入一个替代上述假设的选项。
发布于 2014-07-10 02:38:48
您的主要问题是:0xffffffff
是否没有签名?
取自C11§6.4.4.1整数常数
整数常量的类型是可以表示其值的对应列表中的第一个。
第一个printf
行的输出表明,机器上的int
是32位。因此,它不能表示0xffffffff
,它必须是无符号的。
https://stackoverflow.com/questions/24666567
复制相似问题