Java中的按位与(&)运算符是如何工作的?

43

27
这就是我讨厌 Stack Overflow(以下简称 SO) 的某些用户的原因。为什么有些人不能先在 SO 上提问呢?也许他们已经有了一些基础知识,但认为 SO 是获取答案的最佳地点。 - Mukus
@TejaswiRana - 如果你在网上找不到简单问题的答案,那么通过SO提出这些问题并得到答案会带来更多的伤害而不是好处。你需要先学会如何找到简单问题的答案。有时候,为了真正帮助某人,你必须告诉他们艰难的真相,而不是简单的答案。 - jtahlborn
17
如果有人问我在火车站应该去哪个平台,我会给他们一个简单的答案。我不知道这只是我自己的想法还是别人也会这样做。我知道那个人在来车站之前可能已经搜索过了,但是我明白他们有更多事情要做,而不是听别人讲解,所以我认为给他们简单的答案就足够了,没有必要提供其他信息。 - Mukus
@TejaswiRana - 我理解你的观点,你可以继续在生活中一遍又一遍地分发鱼(给同样的人)。我更喜欢尝试教人们自己捕鱼,因为我相信这将对他们长远更有好处。 - jtahlborn
14
@tjahlborn,他提出这个问题帮助我找到了我正在寻找的答案,所以我感谢他和其他像他一样不遵循你建议的人。 - null
8个回答

68
一个整数在内存中以一系列二进制位的形式表示。为了与人类交互,计算机必须将其显示为十进制数字,但所有的计算都是以二进制进行的。123在十进制中表示为1111011&运算符是按位“与”运算符。结果是两个数字中都打开的位。1001 & 1100 = 1000,因为只有第一位在两个数字中都打开。 |运算符是按位“或”运算符。结果是两个数字中任意一个打开的位。1001 | 1100 = 1101,因为从右边数起的第二位在两个数字中都为零。
还有按位“异或”和按位“非”运算符^~。最后还有左移<<、右移>>和无符号右移>>>运算符。
底层实现上,123存储为01111011 00000000 00000000 0000000000000000 00000000 00000000 01111011,具体取决于系统。使用按位运算符时,使用哪种表示方式并不重要,因为这两种表示都被视为逻辑数字00000000000000000000000001111011。去掉前导零后留下1111011

1
"十进制的123在内存中以1111011存储,但这并不完全准确,因为机器可能采用小端序。" - fge
7
这仍与问题没有关联。 - user207421
2
@Markus 如果没有那个字节序的话,我会给你点赞的。请注意,当操作在寄存器上执行时,数字甚至不需要在内存中。 - starblue
我曾经在一次多项选择中遇到过这个问题,我只有2分钟来解决它。out.println(1234<<6&76543);。是否有任何类似于<<乘以2的基数10的简写方式来执行&操作? - Ian L
@IanLimarta 不行。你必须将数字转换成二进制,通过将它们分解成二的幂之和。1234(十进制)= 1024 + 128 + 64 + 16 + 2 = 1 * 1024 + 0 * 512 + 0 * 256 + 1 * 128 + 1 * 64 + 0 * 32 + 1 * 16 + 0 * 8 + 0 * 4 + 1 * 2 + 0 * 1 = 10011010010(二进制)。 - Markus Jarderot
显示剩余2条评论

9

这是一个二进制AND运算符。它执行的是布尔逻辑中一部分的AND运算,通常用于计算机中的二进制数。

例如:

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

您还可以对多位数执行此操作:
01 & 00 = 00
11 & 00 = 00
11 & 01 = 01
1111 & 0101 = 0101
11111111 & 01101101 = 01101101
...

4
如果你查看在二进制中表示的两个数字,按位与(&)操作可以创建第三个数字,它的每一位都是两个数字相应位都为1的情况(其他位置则为0)。

例如:
0b10011011 &
0b10100010 =
0b10000010


请注意,当两个参数在某个位置都为1时,才会出现1。
按位与操作在每一位存储特定信息的数值时非常有用。
您还可以使用它们通过使用掩码来删除/提取数字的某些部分。

3
如果您按照十六进制代码展开这两个变量,它们分别是:
bitmask : 0000 0000 0000 1111
val:      0010 0010 0010 0010

现在,一个简单的按位与操作得出数字0000 0000 0000 0010,用十进制表示为2。我假设您已经了解基本的布尔运算和数字系统。

1

这是一种对输入值进行的逻辑操作。为了理解,将值转换为二进制形式,当位于位置n的两个位都为1时,结果为1。最后再转换回来。

例如,使用以下示例值:

0x2222 =  10001000100010
0x000F =  00000000001111
result =  00000000000010   => 0x0002 or just 2

0

进行逻辑与位运算,例如4 & 1变成

10 & 01 = 1x0, 0x1 = 00 = 0

n & 1用于检查偶数,因为如果一个数字是偶数,该操作将始终为0。


0

仅仅知道按位与的工作原理是不够的。学习的重要部分是如何应用我们所学到的知识。这里有一个使用按位与的用例。

例如:

将任何偶数的二进制数与1的二进制数相加,结果都为零。因为所有偶数的最后一位(从左到右读)都是0,而唯一的一位1在末尾。

如果你被要求编写一个函数,该函数以数字作为参数,并返回偶数的真值,但不能使用加法、乘法、除法、减法、模运算,也不能将数字转换为字符串。

这个函数是使用按位与的完美用例。正如我之前解释的那样。你问我展示代码吗?这里是Java代码。

/**
 * <p> Helper function </p>
 * @param number
 * @return 0 for even otherwise 1
 */

private int isEven(int number){
    return (number & 1);
}

-1
import.java.io.*;
import.java.util.*;

public class Test {
    public static void main(String[] args) {
        int rmv,rmv1;

        //this R.M.VIVEK complete bitwise program for java
        Scanner vivek=new Scanner();
        System.out.println("ENTER THE X value");
        rmv = vivek.nextInt();
        System.out.println("ENTER THE y value");
        rmv1 = vivek.nextInt();

        System.out.println("AND table based\t(&)rmv=%d,vivek=%d=%d\n",rmv,rmv1,rmv&rmv1);//11=1,10=0
        System.out.println("OR table based\t(&)rmv=%d,vivek=%d=%d\n",rmv,rmv1,rmv|rmv1);//10=1,00=0
        System.out.println("xOR table based\t(&)rmv=%d,vivek=%d=%d\n",rmv,rmv1,rmv^rmv1);
        System.out.println("LEFT SWITH based to %d>>4=%d\n",rmv<<4);
        System.out.println("RIGTH SWITH based to %d>>2=%d\n",rmv>>2);

        for(int v=1;v<=10;v++)
            System.out.println("LIFT SWITH based to (-NAGATIVE VALUE) -1<<%d=%p\n",i,-1<<1+i);
    }
}

基于0和1的位运算符,包括AND和OR,用于根据输出生成真值表。 - R.M.VIVEK Arni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接