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

分手后的思念是犯贱 2022-05-09 03:10 480阅读 0赞

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

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

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

10的原码:00000000000000000000000000001010;

-10的原码:10000000000000000000000000001010;

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

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

-10的反码:11111111111111111111111111110101;

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

10的补码:00000000000000000000000000001010;

-10的补码:11111111111111111111111111110110;

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

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

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

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

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

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

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

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

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

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

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

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

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

请看下面的例子:

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

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

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

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

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

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

发表评论

表情:
评论列表 (有 0 条评论,480人围观)

还没有评论,来说两句吧...

相关阅读

    相关 文章明白差分

    一篇文章讲明白差分 题目 输入一个长度为 n 的整数序列。 接下来输入 m 个操作,每个操作包含三个整数 l,r,c,表示将序列中 \[l,r\] 之间的每个数加

    相关 彻底明白IRP

    微软的东东,多数是把聪明人搞晕,把晕的人搞残,把残的人搞死! 一直以来,想弄明白驱动和IRP到底是怎么回事,在驱网上也查了无数的资料,到头来,手脚抽筋也没弄明白。 从网上查