關於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)

總之,整型所涉及到的操作它都可以更快速的實現,有興趣可以仔細研究。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM