这是对负数的按位运算:
#include <stdio.h>
main()
{
int a = -20, b = 84;
printf("%d", (a>>(a &b)));
}
-20的二进制补码是1100
二进制,84是10000100
。因此a & b
应为100
,但答案为68,总答案为-2。
有人可以向我解释一下吗?
答案 0 :(得分:4)
-20不是1100 2 。它最有可能(如果整数是32位而我们不是在谈论奇数平台),11111111111111111111111111101100 2 。
84不是10000100 2 。它是1010100 2 。
将他们加在一起:
11111111111111111111111111101100
&
00000000000000000000000001010100
=
00000000000000000000000001000100 (68 decimal)
然后你正在向右转移68个位置,这有两个问题:
在普通平台上不太可能有128位的整数。 64位整数是罕见的,但并非不可能,但对于它们68> = 64,所以你应该得到未定义的行为。
现在,这个未定义的行为可能看起来像......
如果我们的int是32位且我们在x86平台上做这个(或者类似的东西),68应该被CPU截断到5位,让你的移位数为68&amp; 31 = 4。
然后,假设SAR
指令(符号保留算术右移)用于>>
,我们得到(-20)SAR 4 = -2:
11111111111111111111111111101100
SAR
4
=
11111111111111111111111111111110 (-2 decimal)
答案 1 :(得分:3)
如果您使用的是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