一篇文章彻底弄明白java中的二进制运算

在java中的二进制运算符有:<<(左移保留符号位), >>(右移保留符号位), >>>(右移,符号位也一起移动), ~(按位取反), ^(异或,相同为0,不同为1), &(逻辑与) ,|(逻辑或),下面我们就来一个一个解释一下。

在说二进制运算之前,我们先来了解一下原码,反码和补码的概念:

原码:第一位是符号位,0表示正数,1表示负数。其余31位为具体的值,例如:

10的原码:00000000000000000000000000001010;

-10的原码:10000000000000000000000000001010;

反码:在原码的基础上,符号位不变,其余的按位取反,例如:

10的反码:11111111111111111111111111110101; //在java中没有用到

-10的反码:11111111111111111111111111110101;

补码:负数的补码就是反码+1,整数的补码就是原码本身

10的补码:00000000000000000000000000001010;

-10的补码:11111111111111111111111111110110;

在java中整数是用补码来表示的,记住正数的补码就是原码本身,负数的补码是反码+1

@org.junit.Test
    public void test5() {
        int a = 10;
        int b = -10;
        System.out.println(Integer.toBinaryString(a)); //1010;toBinaryString方法会省略掉前面的0
        System.out.println(Integer.toBinaryString(b));//11111111111111111111111111110110;确实是反码+1
    }

接下来我们来说二进制移位运算:

value << N :保留符号位,其余的向左移动N位,整数和负数都是低位补0,相当于乘以2的N次方,这种方式用来做2的整数倍乘法运算效率很高。

>>:保留符号位,其余的向右移动N位,整数高位补0,负数高位补1;

>>>:将符号位也一起移动,高位补0,正数跟>>一样,负数因为符号位是1,移动后的结果可能不是我们预期的,

请认真看一下下面的例子:

@org.junit.Test
    public void test6(){
        int a = 10; //00000000000000000000000000001010
        int b = -10; //11111111111111111111111111110110
        System.out.println(a << 2); //40,00000000000000000000000000101000,相当于乘以4
        System.out.println(b << 2); //-40,11111111111111111111111111011000,相当于乘以4
        System.out.println(a >> 2); //2,00000000000000000000000000000010,正数向左移动后,高位是补0,跟符号位一致
        System.out.println(b >> 2); //-3,11111111111111111111111111111101,负数向左移动后,高位时补1,跟符号位一致
        System.out.println(a >>> 2); //40,00000000000000000000000000101000,相当于乘以4
        System.out.println(b >>> 2); //1073741821,00111111111111111111111111111101,将符号位也一起向右移动,高位补0,所以负数会变成一个正数。
    }

接下来我们来说一下二进制的逻辑运算:

&:按位逻辑与,都为1则为1,否则为0;

|:按位逻辑或,都为0则为0,有一个为1则为1;

^:异或,两个都相同为0,两个不相同为1,1^1=0,1^0=1;

~:按位取反,包括符号位;

请看下面的例子:

    @org.junit.Test
    public void test7(){
        int a = 10; //00000000000000000000000000001010
        int b = 9; //00000000000000000000000000001001
        System.out.println(a & b); //8,00000000000000000000000000001000,都为1则为1,否则为0
        System.out.println(a | b); //11,00000000000000000000000000001011,只要有一个为1就为1
        System.out.println(a ^ b); //3,00000000000000000000000000000011,相同为0,不同为1
        System.out.println(~a); //-11,11111111111111111111111111110101,按位取反
    }

以上就是java中的二进制运算,记得以前有一道笔试题,输入两个int的整数a,b,求他们的二进制表示中有多少位相同?

当时想了好久,都没搞定,看完二进制的运算后就变得很简单了,只要用到Integer中提供的bitCount静态方法就可以了,请看:

public void test8() {
        int a = 11; //00000000000000000000000000001011
        int b = 3; //00000000000000000000000000000011
        int count = Integer.bitCount(11 & 3); //预期是2,返回是2
        System.out.println(count);
    }

PS:toBinaryString:返回整数的二进制表示,从第一个不为0的位开始,会省略前面的0

         bitCount:返回二进制中1的个数

猜你喜欢

转载自blog.csdn.net/caishi13202/article/details/82904891
今日推荐