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)
这不是一个假设.你觉得是什么类型的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
因为int
32位且只有31位表示数量signed int
(标准规定一位保留用于符号).unsigned int
因此使用下一种类型.因此,在移位操作中不存在符号位,因此是逻辑而不是算术.
我的结论可能并不明显int
,你的平台上有32位.事实上,我不能做出这样的假设:如果不是第一行,那么算术右移会改变它的价值-1
.这种转变的结果,倾倒为%x
,是0xFFFFFFFF
.有int
过原生64位认为应该转储0xFFFFFFFFFFFFFFFF
代替.如果没有先验知识,则不能0xFFFFFFFF
假设单一类型的结论,因为它可以表示为int
具有值的宽度64位(63 + 1)的标准0x00000000FFFFFFFF
.由此产生的移位将产生您现在看到的相同输出,从而引入上述假设的替代方案.
你的主要问题是:0xffffffff
未签名?
从C11§6.4.4.1整数常量
整数常量的类型是相应列表中可以表示其值的第一个.
第一printf
行的输出表明int
您的计算机上是32位.因此它不能代表0xffffffff
,它必须是无符号的.