为什么屏蔽负数会产生正数?
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
。
正数 3
是 0x00000003
,所以用 0x0000FFFF
掩码可以得到 3
的结果。
如果您指定 16 位数据类型,您将得到您期望的结果,例如
int16_t x = -3;
x &= 0xffff;
cout << x;
在你的例子中,int 超过了 2 个字节。你可能 运行 在现代 CPU 那里通常这些天整数是 4 字节(或 32 位)
如果您看一下系统存储负数的方式,您会发现它是一个补数。如果你只取最后 2 个字节,因为你的掩码是 0xFFFF 那么你将只得到它的一部分。
你的 2 个选项:
- 使用 short 而不是 int。通常是整数的一半,只有 2 位
- 使用更大的掩码,例如 0xFFFFFFFF,它覆盖了整数的所有位
注意:我使用 "usually" 因为你的 int 和 short 中的位数取决于你的 CPU 和编译器。
在 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
。
正数 3
是 0x00000003
,所以用 0x0000FFFF
掩码可以得到 3
的结果。
如果您指定 16 位数据类型,您将得到您期望的结果,例如
int16_t x = -3;
x &= 0xffff;
cout << x;
在你的例子中,int 超过了 2 个字节。你可能 运行 在现代 CPU 那里通常这些天整数是 4 字节(或 32 位)
如果您看一下系统存储负数的方式,您会发现它是一个补数。如果你只取最后 2 个字节,因为你的掩码是 0xFFFF 那么你将只得到它的一部分。
你的 2 个选项:
- 使用 short 而不是 int。通常是整数的一半,只有 2 位
- 使用更大的掩码,例如 0xFFFFFFFF,它覆盖了整数的所有位
注意:我使用 "usually" 因为你的 int 和 short 中的位数取决于你的 CPU 和编译器。