关于Java中位运算符的理解

关于Java中位运算符的理解

1.位运算符认知

这一点算是java基础中的一个黑洞吧,不经常用,可读性也比较差,关键是比较难理解。但最近准备面试的时候看到java源码中用到了很多,看的一脸懵B,逃避不了那就面对它吧!

知识1:Java位运算是针对于整型(byte、char、short、int、long)数据类型的二进制进行的移位操作。

知识2

数据类型位数
byte 8
boolean 8
short 16
int 32
long 64
float 32
double 64
char 16

知识3:计算机表示数字正负不是用+ -加减号来表示,而是用最高位数字来表示,0表示正,1表示负 。

2.位运算符实验

看代码就好了

/**
* @author YuanHaiLiang
* @date 2018-08-14
*/
public class bitOperation {

  /*
  --------------------------------------------------------------------------------------------
  \     &:按位与 \ 如果相对应位都是1,则=为1,否则为0   \ (A&B),得到12,即0000 1100\
    --------------------------------------------------------------------------------------------
  \   |:按位或   \   如果相对应位都是0,则=为0,否则为1   \ (A | B)得到61,即 0011 1101 \
    --------------------------------------------------------------------------------------------
  \   ~:按位非   \ 按位取反运算符翻转操作数的每一位,即01互换\ (〜A)得到-61,即1100 0011   \
    --------------------------------------------------------------------------------------------
  \   ^:按位异或 \   如果相对应位值相同,则=为0,否则为1 \ (A ^ B)得到49,即 0011 0001 \
    --------------------------------------------------------------------------------------------
  \ <<左位移运算符 \ 左操作数按位左移右操作数指定的位数。     \   A << 2得到240,即 1111 0000 \
    --------------------------------------------------------------------------------------------
  \ >>右位移运算符 \ 左操作数按位右移右操作数指定的位数       \   A >> 2得到15即 1111     \
  ----------------------------------------------------------------------------------------------
  \               \   左操作数的值按右操作数指定的位数右移   \                               \
  \ >>> 无符号右移 \   移动得到的空位以零填充                 \   A>>>2得到15即0000 1111   \
  ----------------------------------------------------------------------------------------------
    优先级S:~ 波浪
      优先级A:<<、>>和>>>
          优先级B:&
              优先级C:^ shift+6
                  优先级D:/
    */

  public static void main(String[] args) {
      /* 60 = 0011 1100 */
      /* 13 = 0000 1101 */
      int A = 60;                   int B = 13;                

      System.out.println( "A&B=" + (A&B) );
      System.out.println( "A|B=" + (A|B) );
      System.out.println( "~A=" + (~A) );
      System.out.println( "~A=" + (A^B) );
      System.out.println( "A<<2=" + (A<<2) );
      System.out.println( "A>>2=" + (A>>2) );
      System.out.println( "A>>>2=" + (A>>>2) );

  }

}

结果如下:


A&B=12
A|B=61
~A=-61
~A=49
A<<2=240
A>>2=15
A>>>2=15

3.重点是什么时候用

我为什么要它?

答案1:位运算的运算效率比直接对数字进行加减乘除高很多(至于为什么会快,不明白的可以去搜下为什么C的代码执行速度比Java,python快),代码需要考虑性能的时候

答案2:因为大牛都喜欢这样,估计是炫技吧!

4:使用

场景1:判断奇偶数 a&1 结果为 0 ,a就是偶数 结果为 1 ,a就是奇数

场景2:求平均数 (x+y)/2 这样吗?考虑过 x+y可能超过int的范围吗?正确的姿势是 (x&y)+((x^y)>>1)

场景3:有两个int类型变量x、y,要求两者数字交换,不用临时变量?(当年学java的时候这可是奥数级别的题目) x ^= y; y ^= x; x ^= y;

场景4:求绝对值

int abs( int x ) { int y= x >> 31 ; return (x^y)-y ; //or: (x+y)^y }

场景5:取模 a % (2^n) 等价于 a & (2^n - 1)

场景6:快速乘法 a * (2^n) 等价于 a << n

场景7:快速除法 a / (2^n) 等价于 a >> n

场景8:求相反数 (~x+1)

总之,整型所涉及到的操作它都可以更快速的实现,有兴趣可以仔细研究。

 

posted @ 2018-08-15 01:05  苑海亮  阅读(6590)  评论(0编辑  收藏  举报