Java 位运算符结果是如何产生的?

Java 位运算符结果是如何产生的?,java,bit-manipulation,bitwise-operators,Java,Bit Manipulation,Bitwise Operators,我很惊讶,我在谷歌上找不到这个听起来很简单的问题的答案。在检查了十几个不同的页面后,我想在这里问一下 根据,3和5的结果是1。此外,3 | 5导致7。我唯一的问题是: 我们如何以3和5的价格获得1 我们如何以3 | 5的价格买到7 还有,负数呢 8和-8如何产生8 果不其然,用java编写以下内容: System.out.println(3&5); System.out.println(3|5); System.out.println(8&-8); 生成此输出: 1 7

我很惊讶,我在谷歌上找不到这个听起来很简单的问题的答案。在检查了十几个不同的页面后,我想在这里问一下

根据,3和5的结果是1。此外,3 | 5导致7。我唯一的问题是:

  • 我们如何以3和5的价格获得1
  • 我们如何以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

但同样,这些结果是如何确定/计算的?

此时,您需要将数字转换为二进制。您需要记住,“b1和b2=1”仅当它们都为1时,而“b1或b2=0”仅当它们都为0时

比如说

5 or 3 = 101 or 011 = 111 = 7
5 and 3 = 101 and 011 = 001 = 1
3和5:

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有效地补足),并对最右边的一的左边的所有内容进行补码:

00001000 // 8
00000111 // 8 - 1 = 7
11111000 // -8
请注意,如果使用8位数字,则-8仅为11111000。如果你有更多的比特,左边会有更多的1。如果你只有4位,你会遇到一些麻烦,因为-8和8有着相同的表示形式,所以-8(在4位数学中)是一个自身为负数的数字(比如零)

实际上,8不是一个很好的例子,因为它太简单了。让我们做
100&-100
(100,而不是4):

现在与100:

01100100 // 100
10011100 // -100
-------- AND
00000100 // 4
通常,
x&-x
会隔离最右边的1。最右边的零和最右边的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

同样的想法,以及每个运算的真值表,并将它们应用于您的特定问题。

将您的数字转换为二进制表示,然后尝试。查看整数。当你在使用它时,请查看toBinaryString(int)。我想大多数写这篇文章的人都假设你已经知道计算机中的数字是用二进制表示的……至于
8&-8
部分:我有点怀疑,但我不完全确定。我将把这个问题留给更有知识的人(如果你愿意,可以在我的帖子中随意编辑)。谢谢你的解释。所以我假设如果有一个语句,比如
if((3 | 5)==7){…}
,那么java隐式地将3和5转换成二进制,并进行OR比较,得到7。我只是错过了你解释中的额外工作。但是现在我明白了。
|
&
是二进制比较符号(它们在二进制级别上比较两个参数)<代码>|和
&&
是逻辑比较符号。
01100100 // 100
10011100 // -100
-------- AND
00000100 // 4
  0011
& 0101
------
  0001 => 1 in decimal