C 负数按位

C 负数按位,c,C,以下是负数的按位运算: #include <stdio.h> main() { int a = -20, b = 84; printf("%d", (a>>(a &b))); } #包括 main() { INTA=-20,b=84; printf(“%d”,(a>>(a&b)); } 2的-20补码是二进制的1100,84是10000100。因此a&b应该是100,但答案是68,总体答案是-2 有人能给我解释一下吗?如果你使用的是Windo

以下是负数的按位运算:

#include <stdio.h>

main()
{
    int a = -20, b = 84;
    printf("%d", (a>>(a &b)));
}
#包括
main()
{
INTA=-20,b=84;
printf(“%d”,(a>>(a&b));
}
2的-20补码是二进制的
1100
,84是
10000100
。因此
a&b
应该是
100
,但答案是68,总体答案是-2


有人能给我解释一下吗?

如果你使用的是Windows,它应该附带一个支持二进制的计算器应用程序。 这是一个很好的可靠的计算来源。 您可以选择
Word
,它是一个int

负数通过左侧的所有位1记录在内存中。所以-20是

  1111-1111-1110-1100
= 0xFFEC
84是:

  0000-0000-0101-0100
= 0x0054
和是一种逐位操作,它比较两个传递的数字,检查每个位。如果两个位均为1,则结果位为1。否则它是零。所以

  1111-1111-1110-1100
& 0000-0000-0101-0100
= 0000-0000-0100-0100
= 68
-20不是11002。最有可能的情况是(如果INT是32位的,我们不是说奇数平台),111111111111011002

84不是100001002。是10101002

将它们放在一起:

11111111111111111111111111101100
&
00000000000000000000000001010100
=
00000000000000000000000001000100 (68 decimal)
然后你要向右移动20到68个位置,这有两个问题:

  • 负整数的右移是实现定义的,编译器的实现是什么
  • 按值中的位数或超过该位数的移位会导致未定义的行为
128位整数在通用平台上不太可能出现。64位整数很少见,但并非不可能,但对于它们来说68>=64,因此应该得到未定义的行为

现在,这个未定义的行为看起来像什么

如果我们的INT是32位的,并且我们在x86平台上(或其他非常类似的平台)执行此操作,那么68应该被CPU截断为5位,这样您的移位计数为68&31=4

然后,假设
SAR
指令(保留符号的算术右移)用于
>
,我们得到(-20)SAR 4=-2:

11111111111111111111111111101100
SAR
4
=
11111111111111111111111111111110 (-2 decimal)