我很惊讶在谷歌上找不到这个听起来很简单的问题的答案。在查看了大约十几个不同的页面后,我只想问一下。。。
根据该页面,3&5得到1。同样,3|5得到7。我唯一的问题很简单:
- 我们如何获得1换3&5
- 我们如何获得3|5的7
还有,负数呢?
- 8&-8的结果是8
果不其然,用java编写以下内容:
System.out.println(3&5);
System.out.println(3|5);
System.out.println(8&-8);
产生此输出:
1
7
8
但是,这些结果是如何确定/计算的呢?
3&5:
0011
0101
----- AND
0001 == 1
3|5:
0011
0101
----- OR
0111 == 7
Java中的否定被定义为二的补码否定(这是非常常见的)
所以-x = ~x + 1 = ~(x - 1)
。
8&-8:
00001000 //8
11111000 //-8
-------- AND
00001000 // 8
使用否定的最后一个定义,-1首先借用所有最右边的零(如果有的话),并按原样设置它们,直到它达到1,它重置了1,左边的任何东西都没有修改。补码然后恢复最右边的0和最右边的1(所有这些都被-1有效补码),并补码最右边的左边的所有内容:
00001000 // 8
00000111 // 8 - 1 = 7
11111000 // -8
请注意,如果使用8位数字,-8仅为11111000。如果你有更多的比特,左边就会有更多的1。如果你只有4位,你会遇到一些麻烦,因为-8和8的表示方式相同,所以-8(在4位数学中)是一个负数(比如零)。
事实上,8不是一个很好的例子,因为它太简单了。让我们做100 & -100
(百,而不是4):
01100100 // 100
01100011 // 99
10011100 // -100
现在&带100:
01100100 // 100
10011100 // -100
-------- AND
00000100 // 4
一般来说,x & -x
分离最右边的1。最右边的0和最右边的1都不受否定的影响,所以只对数字的这一部分,看起来你在做x & x
(当然是x
)。上半部分,在最右边的一个的左边,是互补的,所以你有1的地方都变成了0,你有一个1的地方变成了0。0 & 1 = 0
,所以处处都是0。
3&5=>1
二进制中的3是0011。
二进制中的5是0101。
应用逐位和
0011
& 0101
------
0001 => 1 in decimal
采用相同的想法,以及每个操作的真相表,并将其应用于您的特定问题。
您需要将数字转换为二进制,此时您需要记住"b1和b2=1"仅当它们都是1,"b1或b2=0"仅当他们都是0。
例如
5 or 3 = 101 or 011 = 111 = 7
5 and 3 = 101 and 011 = 001 = 1