位運算

1、什麼是位運算?

位運算(Bit Manipulation,也叫位操做)說穿了,就是直接對整數在內存中的二進制位進行操做。
html

優先級(能夠放在最後記憶)算法

運算符優先級

2、優勢、缺點。

2.1 優勢,同時也能夠理解爲:1.位運算有什麼用; 2.用在什麼地方。

  1. 提升速度,節省空間(有時也能節省代碼量)。
    由於位運算是直接操做二進制,因此避免了進制轉換,類型轉換提升了計算速度。如5<<3 至關於 52^3=58=40;
    對於這一點速度,對於語言高級層面可能顯得並不那麼重要,但在低層(大量使用時或循環中),就很明顯了。
    注:嵌入式,硬件,驅動,編碼
  2. 聯合表示多個bool值。
    一個byte能夠存儲8個邏輯值,在算法競賽中,狀態壓縮是最明顯的一個應用。
  3. 有些地方咱們必需要使用位運算來處理,好比權限。
    a&~b: 清除標誌位b;
    a|b: 添加標誌位b;
    a&b: 取出標誌位b;
    a^b: 取出a與b的不一樣部分;
public class Permission {
    // 是否容許查詢
    private boolean allowSelect;
    // 是否容許新增
    private boolean allowInsert;
    // 是否容許刪除
    private boolean allowDelete;
    // 是否容許更新
    private boolean allowUpdate;
    // 省略Getter和Setter
}

public class NewPermission {
    // 是否容許查詢,二進制第1位,0表示否,1表示是
    public static final int ALLOW_SELECT = 1 << 0; // 0001
    // 是否容許新增,二進制第2位,0表示否,1表示是
    public static final int ALLOW_INSERT = 1 << 1; // 0010
    // 是否容許修改,二進制第3位,0表示否,1表示是
    public static final int ALLOW_UPDATE = 1 << 2; // 0100
    // 是否容許刪除,二進制第4位,0表示否,1表示是
    public static final int ALLOW_DELETE = 1 << 3; // 1000
    // 存儲目前的權限狀態
    private int flag;

    //從新設置權限
    public void setPermission(int permission) {
        flag = permission;
    }
    //添加一項或多項權限
    public void enable(int permission) {
        flag |= permission;
    }
    //刪除一項或多項權限
    public void disable(int permission) {
        flag &= ~permission;
    }
    //是否擁某些權限
    public boolean isAllow(int permission) {
        return (flag & permission) == permission;
    }
    //是否禁用了某些權限
    public boolean isNotAllow(int permission) {
        return (flag & permission) == 0;
    }
    //是否僅僅擁有某些權限
    public boolean isOnlyAllow(int permission) {
        return flag == permission;
    }
}

2.2 缺點

缺點其實很明顯:編碼

  1. 不瞭解位運算的人可能徹底看不懂;
  2. 可讀性差,即便對位運算相對比較瞭解的人 一會兒也可能感受不明因此。

3、詳解位運算符

3.1 按位與運算(&), 同爲1,則爲1.

含義(用法):按位與運算一般用來對某些位清0或保留某些位。
如:a&255或a&0xff,由於255的二進制爲1111 1111,與的結果爲a只保留低8位。
再如:a = a&(~7),由於~7爲1111 1000(假如1個字節),與的結果爲a的低3位置爲0。

注:code

  • 255,7等數字並不是隨意,須要根據本身的意圖選取,如使a的第2個字符轉爲0,a&(~0xF0)
  • 當初我就迷惑:僅僅將某此位轉爲0或1有何用?(後來明白跟其它位運算符結合使用都會突顯各自的做用)

3.2 按位或運算(|),有1,則爲1.

含義(用法):將某些位置爲1.
如:8|4 => 1000b|0100b => 1100b =>12,單看沒啥用,若是用在權限上(授予權限),嘖嘖..

3.3 按位異或運算(^),不一樣,則爲1.

含義(用法):求出兩個數的差別。

3.4 求反運算(~),1則爲0,0則爲1.

3.5 左移<<,右移>>,無符號右移>>>.

1. <<n左移n位,右補0。實際含義至關於*2^n
2. >>n右移n位,左補0.實際含義至關於/2^n
3. >>>n右移n位,正數左補0,負數取決於編譯系統,通常補1

4、經常使用操做

  1. 平均值
    (x+y)>>1
  2. 2的n次方
    1 << n
  3. 判斷符號是否相同
    (x^y)>=0
  4. 交換兩個數
    a ^= b;
    b ^= a;
    a ^= b;
  5. 判斷奇偶性
    (n &1) ==1
  6. 取絕對值
    (n ^ (n >> 31)) - (n >> 31)
  7. 判斷n是不是2的整數次冪
    n&(n-1) == 0
  8. 其它
1.將expr的第n(n從0開始)位設置爲1: expr |= (1<<n);
2.將expr的第n(n從0開始)位設置爲0: expr &= (~(1<<n));
3.判斷expr的第n(n從0開始)位是否爲1:bool b =expr & (1<<n);
4.翻轉expr的第n(n從0開始)位:expr ^=(1<<n);

5、連接、參考、QQ羣

  1. 本文連接做業部落
  2. 簡書文集之二進制
  3. QQ羣之專精位運算,點擊便可加羣662979096
相關文章
相關標籤/搜索