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)
總之,整型所涉及到的操作它都可以更快速的實現,有興趣可以仔細研究。