C Negation运算符在Debian终端中打印出意外的结果

时间:2017-04-15 22:00:38

标签: c gdb

这纯粹是学术性的,但我在C中创建了一个简单的真值表:

#include <stdio.h>

int main() {
  for(int j=0; j<=2; j++) {
    int bitB = (j&1);
    printf("~%d = %d\n", bitB, ~bitB);
  }
  return 0;
}

在终端中运行产生:

~1 = -2
~0 = -1

通过在printf上设置中断来调试gdb会产生我期望的结果:

(gdb) print bitB
$5 = 1
(gdb) cont
Continuing.
~1 = -2
(gdb) x/xw &bitB
0xbffff3d8: 0x00000000

为什么程序输出显示负数?

3 个答案:

答案 0 :(得分:3)

这是一个完美预期的结果,至少在two's complement system表示负数的系统中:

  • 负数表示所有位设置为1
  • 除了最后一位之外,负二将所有位设置为1

因此,翻转所有的零位会产生-1,并且翻转1的所有位会产生-2

0000000000000000 -> 1111111111111111 // Zero becomes negative 1
0000000000000001 -> 1111111111111110 // One becomes negative 2

在数学上,要翻转二进制补码表示中数字的符号,请翻转数字的所有位,然后将1添加到结果中。只需翻转x的所有位,即可生成-x-1。这正是你看到的结果。

  

为什么程序输出显示负数?

因为您使用带有int格式说明符的带签名的%d,并且您打印的位模式恰好是负数的表示。

答案 1 :(得分:0)

在所有系统和数字表示中,这将给出负数。您正在补充所有位,包括符号位。

答案 2 :(得分:-1)

因为您使用类型int(包含其符号),并且反转最高位也会根据Two's complement规则更改符号(请注意~反转/补充所有位)

如果您希望unsigned int为您提供无符号的表示,您可能希望使用%u(和~)。