奇怪的右移位不一致
Bizarre right bitshift inconsistency
我一直在使用 C 中的位(运行 在 ubuntu 上)。在使用两种不同的方式右移整数时,我得到了奇怪的不同输出:
#include <stdio.h>
int main(){
int x = 0xfffffffe;
int a = x >> 16;
int b = 0xfffffffe >> 16;
printf("%X\n%X\n", a, b);
return 0;
}
我认为每个输出都是相同的:FFFF,因为右边的四个十六进制位置(16 位)被右移了。相反,输出是:
FFFFFFFF
FFFF
如何解释这种行为?
当你说:
int x = 0xfffffffe;
这会将 x
设置为 -2,因为 int
可以在此处保存的最大值是 0x7FFFFFFF
并且它在转换期间回绕。当您对负数进行位移时,它会变得 weird.
如果您将这些值更改为 unsigned int
,一切都会成功。
#include <stdio.h>
int main(){
unsigned int x = 0xfffffffe;
unsigned int a = x >> 16;
unsigned int b = 0xfffffffe >> 16;
printf("%X\n%X\n", a, b);
return 0;
}
您在此处看到的行为与移位有符号或无符号整数有关,这会产生不同的结果。
无符号整数的移位是 合乎逻辑的 。相反,有符号整数的移位是算术。 编辑: 在 C 中,它是实现定义的,但 通常 是这种情况。
因此,
int x = 0xfffffffe;
int a = x >> 16;
这部分执行算术移位,因为 x 是 有符号。并且因为 x 实际上是负数(二进制补码中的 -2),x 是 符号扩展 ,因此附加“1”导致 0xFFFFFFFF。
相反,
int b = 0xfffffffe >> 16;
0xfffffffe 是一个被解释为 无符号 整数的乱码。因此,逻辑 移位 16 结果如预期的那样为 0x0000FFFF。
我一直在使用 C 中的位(运行 在 ubuntu 上)。在使用两种不同的方式右移整数时,我得到了奇怪的不同输出:
#include <stdio.h>
int main(){
int x = 0xfffffffe;
int a = x >> 16;
int b = 0xfffffffe >> 16;
printf("%X\n%X\n", a, b);
return 0;
}
我认为每个输出都是相同的:FFFF,因为右边的四个十六进制位置(16 位)被右移了。相反,输出是:
FFFFFFFF
FFFF
如何解释这种行为?
当你说:
int x = 0xfffffffe;
这会将 x
设置为 -2,因为 int
可以在此处保存的最大值是 0x7FFFFFFF
并且它在转换期间回绕。当您对负数进行位移时,它会变得 weird.
如果您将这些值更改为 unsigned int
,一切都会成功。
#include <stdio.h>
int main(){
unsigned int x = 0xfffffffe;
unsigned int a = x >> 16;
unsigned int b = 0xfffffffe >> 16;
printf("%X\n%X\n", a, b);
return 0;
}
您在此处看到的行为与移位有符号或无符号整数有关,这会产生不同的结果。 无符号整数的移位是 合乎逻辑的 。相反,有符号整数的移位是算术。 编辑: 在 C 中,它是实现定义的,但 通常 是这种情况。
因此,
int x = 0xfffffffe;
int a = x >> 16;
这部分执行算术移位,因为 x 是 有符号。并且因为 x 实际上是负数(二进制补码中的 -2),x 是 符号扩展 ,因此附加“1”导致 0xFFFFFFFF。
相反,
int b = 0xfffffffe >> 16;
0xfffffffe 是一个被解释为 无符号 整数的乱码。因此,逻辑 移位 16 结果如预期的那样为 0x0000FFFF。