按位非(〜)运算符需要澄清

时间:2010-09-12 18:17:30

标签: c binary logic bitwise-operators

假设您有以下C代码。

 unsigned char a = 1;

 printf("%d\n", ~a); // prints -2
 printf("%d\n", a); // prints 1

我很惊讶地发现 - 由于~1转换打印了-2:

<00>与0000 0001相反的是1111 1110.这不是-2。

我在这里缺少什么?

3 个答案:

答案 0 :(得分:10)

这是两个补充。

在二进制补码表示中,如果数字x的最高有效位为1,则实际值为 - (~x + 1)。

例如,

0b11110000 = -(~0b1111 + 1) = -(15 + 1) = -16.

这是负数的自然表示,因为

0000001 =  1
0000000 =  0
1111111 = -1  (wrap around)
1111110 = -2
1111101 = -3 etc.

有关详细信息,请参阅http://en.wikipedia.org/wiki/Two%27s_complement


顺便说一句,要打印无符号值,请使用%hhu%hhx格式。请参阅http://www.ideone.com/YafE3

答案 1 :(得分:4)

%d代表带符号的十进制数,而不是无符号。因此,即使存储在无符号变量中,您的位模式也会被解释为带符号的数字。

请参阅此Wikipedia entry on signed number representations以了解位值。特别参见Two's complement

答案 2 :(得分:0)

考虑有符号数学的一种(温和的幽默)方法是认识到最重要的位实际上代表了它上面的无限位数。因此,在16位有符号数中,最高有效位是32768 + 65536 + 131072 + 262144 + ...等。这是32768 *(1 + 2 + 4 + 8 + ...)使用幂级数的标准公式,(1 + X + X ^ 2 + X ^ 3 + ...)= 1 /(1-X ),一个发现(1 + 2 + 4 + 8 + ...)是-1,所以这些位的总和是-32768。