遍地都是的位運算,關鍵時刻竟然有妙用!

2021-09-11 14:29:52 字數 2434 閱讀 9694

很多人都可能在面試的時候遇到過這樣一道題目:

有 1000 個一模一樣的瓶子,其中有 999 瓶是普通的水,其中有一瓶含有劇毒(稀釋後仍然具有毒性),你只有 10 條小白鼠,它們在喝下毒藥後會馬上死去,怎樣利用它們在最短的時間內判斷出哪瓶是毒藥?

我們都知道,在計算機語言當中,所有的數字最終都會轉化為二進位制進行計算,而二進位制中每乙個「位」能夠表示兩種狀態,它們分別是數字 0 和 1。

回到剛才的題目,每條小白鼠的生和死的狀態都可以表示二進位制中的乙個「位」, 10 條小白鼠一共就能表示 1024 種組合狀態,因此這道題目乙個解決思路就是,給這 1000 瓶水都按照二進位制的格式標上記號(10 位二進位制數就能標記全部),讓這 10 條小白鼠分別對應這十位二進位制中的一位,然後將這十位二進位制數中當前位上是 1 的水混合在一起給對應此位的小白鼠喝,根據小白鼠的死亡情況就能定位哪瓶水有毒。

在 android 開發中,我們也時常見到位運算的身影。在進行自定義 view 的時候,都會用到 int makemeasurespec(int size, int mode) 方法去獲取 view 的尺寸和測量模式,那麼它是怎麼把兩個變數組裝成乙個的呢?簡單地講就是用乙個 32 位二進位制數字中的高兩位來儲存測量模式 measuremode,用低 30 位來儲存尺寸 measuresize,measurespec 是 android.view.view 類中的乙個內部類,關鍵**如下:

public static class measurespec  else 

}//獲取 specmode

public static int getmode(int measurespec)

//獲取 specsize

public static int getsize(int measurespec)

}複製**

位運算常用的操作符有以下幾種:

或運算子| :0|0=0,0|1=1,1|1=1

與運算子& :0&0=0,0&1=0,1&1=1

非運算子~ :~0=1,~1=0

異或運算子^ :相同為 0,不同為 1:0^0=0,1^0=1,0^1=1,1^1=0

右移運算子 >> 和左移運算子 << :001<<2=100,110>>1=11

在 measurespec 類中,getmode 方法是將引數 measurespec 與 mode_mask 進行與運算,mode_mask 可以理解為 specmode 的掩碼,運算的結果是保留measurespec 的高兩位,剩下的後 30 位置 0,得到的是 measuremode。

getsize 方法是先將 mode_mask 取反再跟 measurespec 進行與運算,結果是高兩位為 0 低 30 位不變的值,即 specsize。

makemeasurespec 方法中,size & ~mode_mask 的結果是 size 的 specsize,mode & mode_mask 的結果是 specmode,將他們進行或操作,得到的就是是兩者的疊加值。

類似的,在日常開發中,我們也可以用位運算來簡化一些操作,假如服務端返回乙個數字,可能存在幾種狀態疊加的情況(下圖),如果按照傳統的方法來處理將會很麻煩,這時候就需要利用位運算了。

我們可以新建乙個 statusmanager 類用來處理這個複雜的狀態:

public class statusmanager 

/*** 新增一種或者多種狀態

*/public void addstatus(int status)

/*** 刪除一種或者多種狀態

*/public void deletestatus(int status)

/*** 是否具有某些狀態

*/public boolean hasstatus(int status)

/*** 是否不具有某些狀態

*/public boolean ishasnotstatus(int status)

/*** 是否僅僅具有某些狀態

*/public boolean isonlyhas(int status)

}複製**

新增狀態時,可以這樣寫:

manager.addstatus(statusmanager.status_time_asy | status_add_fixed_psw )

複製**

如果需要判斷是否時間同步和開門指令同時失敗,可以這樣寫:

manager.hasstatus(statusmanager.status_time_asy | status_open_door)

複製**

這時候回去理解文章開頭的面試題目是不是很容易了?

mac環境下使用mysql插入中文都是??的問題,

error 1366 hy000 incorrect string value xe4 xb8 x8a xe6 xb5 xb7 for column city at row 1 在使用mac電腦中mysql資料庫的過程中,遇到乙個問題,向乙個資料表中插入資料時,由於其中乙個欄位的值是中文,資料庫報錯...

賺錢第二定律 金錢遍地都是,賺錢很容易

物以類聚,錢以人分。你必須對錢有濃厚的興趣,感覺賺錢很有意思,很好玩,你喜歡錢,錢才能喜歡你。這決不是拜金主義,而是金錢執行的內在規律,不信你看那些富翁都喜歡錢,都能把錢玩得非常了得,看看比爾蓋茨,看看沃倫巴菲特,看看喬治索羅斯。金錢遍地都是,賺錢很容易。你必須確立這樣的觀念。如果你覺得賺錢很難,那...

位運算(1) 初識位運算

前段時間數電課學了些進製轉換,還有與或非等邏輯運算,如今再來看看位運算,倒輕鬆了不少。很早就想寫些非總結性部落格了,奈何還是太懶。也也不知怎的突然又來了興致,趕忙寫下這篇部落格。廢話不多說,今天準備總結總結關於位運算的知識。程式中的所有數在計算機記憶體中都是以二進位制的形式儲存的,即0 1兩種狀態,...