#include<stdio.h>
void main()
{
int a, b, c;
a=5;
b=8;
c= ~(a|b);
printf("%d",c);
}
预期的输出-13
但结果显示-14
。怎么- 14
?
因为你有一个 2 的补码计算机。
- 5 | 8 给出二进制
0101 | 1000 = 1101
= 13 dec。 - 用
~
反转这个,你会得到1111....0010
. - 将其表示为有符号类型,那么在 1 的补码中,这将是 -13 dec。
- 但是对于 2 的补码,我们减去 1 并得到 -14 dec。
出于与 ~0
给出 2 的补码相同的原因-1
而不是-0
.
您将补码与 1 (~( 混淆,将补码混淆为二/一元运算符 -
~(5|8)
是-(5|8) - 1
所以-13 - 1
所以-14
这是由于负数的二进制补码表示。 二的补码是通过反转所有位然后加一个来执行的。
首先,你有a|b
(为了简单起见,我只显示低阶 8 位(:
a 00000101 5
| b 00001000 8
------------
00001101 13
然后按位 NOT:
~ 00001101 13
----------
11110010 -14
对正值执行按位 NOT 不会给你它的负值,它会给你少一个。
假设您使用 8 位整数:
-
a=5
表示为00000101
-
b=8
表示为00001000
-
a|b
00001101
当你反转位时,它将是11110010
,这在 Two 的补码中是 -14
。
这是因为 2 的补码。
使用 8 位有符号值(它与 32 位有符号相同,但这更容易演示(:
8: 00001000
5: 00000101
8 | 5: 00001101
~(8 | 5): 11110010 = 242 (unsigned)
当 MSb 高时做 2 补码的快速方法是减去 2^n(这里 n 是 8,2^8 是 256(
242-256=-14