1. 程式人生 > >Android原始碼中的巧妙的位運算

Android原始碼中的巧妙的位運算

                                                           與或非是啥?

常用的位運算子: “&”   “|”    “~”(與   或  非)。

1,“&”運算子的運算規則:兩個運算位同時為1時結果為“1”,否則為“0”。

     如:1&0=0;    1&1=1;   0&0=0;   0&1=0;

2,“|”運算子的運算規則:兩個運算位只要有一個為“1”時結果為“1”,否則為“0”。

    如:1|1=1;     1|0=1;   0|1=1;   0|0=0;

3,“~”運算子的運算規則:如果位為“0”,結果為“1”,如果位為“1”,結果為“0”

   如:~0=1;   ~1=0;

    但是,在計算機中不是這樣的,結果為:

    System.out.println("~0="+~0);  結果為:-1

    System.out.println("~1="+~1);  結果為:-2

  解析:這並不是計算機出問題了,而是計算機內部編碼的原因。

4,計算機內部編碼:

     對於整數,計算機內部最高位表示符號位: 0為正    1為負。

     對於負數,為了方便計算,計算機用補碼錶示其值。(原碼到補碼的轉換規則:除符號位外,原碼各位取反,然後加1得到補碼)。

    解釋為啥~0=-1:

    0在計算機中的二進位制形式: 0000  0000

    0經過非運算(“~”)後:        1111   1111   (計算機中存的都是原碼)

         反碼:                                1000  0000

         補碼:                                1000  0001  (即:-1)

                                                            在Android中的應用

1,場景一:或運算子的使用

      android:layout_gravity="bottom | right"    在這裡bottom和right在位上肯定是錯開的,這樣才能同時儲存該控價“居右”和“底部”的屬性。

//0x001=0000 0001
int right=0x001;
//0x002=0000 0010
int bottom=0x002;
//那麼 right|bottom= 0000 0011

  上面的位錯開是為了或運算時,進行值的保留。這樣兩個狀態就能夠儲存在一個屬性裡面啦。

暫時可以理解為將兩個狀態放在一個集合裡

 2,場景二:與運算的使用

    上面介紹瞭如何組裝一個值。安卓原始碼中怎樣知道我們設定了right這個居右的狀態呢?這就需要“與”運算來取值。

int right=0x001;
int bottom=0x002;
int top=0x008;
int state=right | bottom;
system.out.println("是否存在right="+((state & right)==right));
system.out.println("是否存在top="+((state & top)==top));

//列印結果: 是否存在right=true;    是否存在top=false;

      從上面程式碼可以清晰的看出,用“與”運算子可以取值  、判斷是否存在這個狀態。

  (暫時可以理解成判斷某個狀態是不是在集合裡)、

3,場景三:非運算的使用

   當我們想剔除集合中的一個狀態的時候要怎麼做呢?  用 “非”和“與”運算子聯合使用,如下程式碼。

int right=0x001;   //1
int bottom=0x002;  //2
int top=0x008;     //8
int state=right | bottom;   //3
System.out.println("剔除rightz狀態前"+state);   //剔除rightz狀態前 3
state&=~right;
System.out.println("剔除rightz狀態後"+state);   //剔除rightz狀態後 2
state&=~top;
System.out.println("剔除不存在的狀態top後"+state);   //剔除不存在的狀態top後 2

如上就可以通過 “與” “非”的聯合運算實現剔除集合中狀態的功能。

總結:

     或運算子整合值(組成狀態集合)

     與運算子取值(集合中取出狀態)

     與非剔除值(集合中移除狀態