为什么“ -10&5”的结果等于4?当按位AND应用于负数时会发生什么?

时间:2019-05-27 10:03:55

标签: c bit-manipulation operators bitwise-operators negative-number

我编写并编译了以下代码:

void main()
{ 
    printf("%d", -10 & 5);
}

当我运行它时,它输出值4。为什么该程序的输出为4?

1 个答案:

答案 0 :(得分:6)

在C中,根据二进制&的结果,每个位取决于操作数中的两个相应位。如果两个操作数中相同位置的位都设置为(1),则结果中将其设置为1。如果在任一操作数中清除为(0),则结果为清除。例如,对于给定的0011和0101位,&运算符将产生0001,因为两个操作数中设置的位仅在最后位置。

您可能已经知道,正整数用二进制表示。位的位置从“右侧”的0开始编号,然后是下一个位置的1、2、3,依此类推。位置 i 中的位代表2 i 的值,因此位0代表1,位1代表2,位2代表4,位3代表8,位4代表16,依此类推。所有位表示的值是设置为1的位的值的总和。所以101表示5,因为2 2 = 4和2 0 = 1,并且4 + 1 = 5。

C标准规定了C实现可用于表示负数的三个规则(在C 2018 6.2.6.2 2中):

  • 一位代表一个符号。如果符号位为0,则该值与上述相同。如果符号位为1,则取反。因此,如果第一位是符号位,则5为0101为5,而-5为1101。这称为符号和幅度
  • 其中一位代表一个符号,如果数字为负,则所有位都将反转。所以5是0101,而-5是1010。这称为一个补码
  • 其中一位代表一个符号,如果数字为负(我们称它为 x ),则将这些位设置为用于2 N - x ,其中 N 是位数。例如,对于四个位,2 N = 16,而5为0101,并且-5用16-5 = 11的位表示1011。这称为补码

在早期的计算机硬件和软件中,尝试了所有上述方法。最后,两个补码在现代整数计算中占绝对优势。 (大多数浮点使用符号和大小。)尽管如此,C标准仍然允许实现使用任何方法。

因此,-10 & 5的结果取决于实现。我将说明使用八位,并留出一个空格将它们分成两组,每组四位,以提高可视性:

有两个补码:

  • -10用1111 0110表示(256-10 = 246 = 128 + 64 + 32 + 16 + 4 + 2),5使用0000 0101,而−10 & 5是0000 0100,表示4。 / li>

补全:

  • -10用1111 0101表示,5使用0000 0101,而−10 & 5是0000 0101,表示5。

具有符号和大小:

  • -10用1000 1010表示,5使用0000 0101,而-10 & 5是0000 0000,表示0。

因此,符合C标准的C实现可能会为-10 & 5产生0、4或5,但是4是迄今为止最常见的结果。