为什么掩盖一个负数会产生一个正数?

Why does masking a negative number produce a positive number?

本文关键字:一个 掩盖 为什么      更新时间:2023-10-16

在c++中,我有以下代码:

int x = -3;
x &= 0xffff;
cout << x;

这生产

65533

但是如果我去掉负号,就有了这个

int x = 3;
x &= 0xffff;
cout << x;

我简单地得到3作为结果

为什么第一个结果不产生负数?我希望-3是扩展到16位的符号,考虑到所有扩展的位都是1,它仍然会得到一个2补的负数。因此,最高有效位也是1。

看起来您的系统使用32位int和二进制补码表示负数。

常数0xFFFF覆盖最不重要的两个字节,上面两个字节为零。

-3的值是0xFFFFFFFD,所以用0x0000FFFF屏蔽它,你得到0x0000FFFD,或者十进制的65533

30x00000003,所以用0x0000FFFF屏蔽会得到3

如果您指定16位数据类型,您将得到您期望的结果,例如

int16_t x = -3;
x &= 0xffff;
cout << x;

在您的示例中,int大于2个字节。您可能运行在现代CPU上,通常这些天的整数是4字节(或32位)

如果你看一下系统存储负数的方式,你会发现它是一个互补数。如果你只取最后2字节作为你的掩码是0xFFFF,那么你只会得到它的一部分。

你的2个选项:

  1. 使用short代替int。通常是整数的一半,只需要2个字节
  2. 使用更大的掩码,如0xFFFFFFFF,它覆盖了你的整数的所有位

注意:我使用"通常"是因为int和short的位数取决于你的CPU和编译器。