为什么屏蔽负数会产生正数?

Why does masking a negative number produce a positive number?

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

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

这会产生

65533

但是如果我去掉负数,那么我有这个:

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

我只是得到 3 作为结果

为什么第一个结果不是负数?我希望 -3 将被符号扩展到 16 位,这仍然应该给出一个二进制补码负数,考虑到所有这些扩展位都是 1。因此最高有效位也将是 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,它覆盖了整数的所有位

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