2013-04-25 54 views
2

我在回顧一些來自鬧鐘項目的代碼。該代碼使用整數來存儲重複出現的警報信息。也就是說,每發生一次MWF,就會發生一次警報。我知道整數只是一系列字節,每個字節都是一系列的位,所以您可以使用該位信息來創建一個整數,該整數對於每週的每個星期幾的每個模式都是唯一的。我不明白的是在這些功能的邏輯:Java位移...請解釋

// is a given day "set"? 
private boolean isSet(int day) { 
    return (mDays & (1 << day)) > 0; 
} 

// set a given day to on or off 
public void set(int day, boolean set) { 
    if (set) { 
     mDays |= (1 << day); 
    } else { 
     mDays &= ~(1 << day); 
    } 
} 

可能有人請解釋一下這兩個功能,以及它們是如何工作的?

回答

6

的isSet功能:

基本上表達:

(1 << day) 

手段搭1:

00000001 

而且隨着day數量的位置向左側的移動它。比如,如果day是3,你必須:

00001000 

可以使用按位&操作員檢查常見位。如:

00001000 
& 
00001000 

將等於

00001000 

然而,

00001000 
& 
00000001 

將等於0。利用這一點,您可以檢查是否該特定位被設置,因爲如果你&你正在尋找的位數,如果該位匹配,你保證得到一個超過0的數字。

SET功能:

表達:

mDays |= (1 << day); 

等同於:

mDays = mDays | (1 << day); 

這將基本上強制位與(1 << day)表示是真實的。假設我們想翻轉一號位:

00001000 | 00000001 
Equals: 
00001001 

表達:

mDays &= ~(1 << day); 

基本上會做的倒數。 ~運算符反轉比特(每1變爲0,每0變爲1)。這將確保您設置的位變爲0,因爲任何東西& 0都是0。由於~(1 << day)中的其他位全部爲1,所以現有位將保留。

+1

「(二進制)00000001 << 1 == 00000010」 = 00000100'。值得一提的是,當它們從位'(二進制)11000001 << 1 == 10000010'和((二進制)11000001 >> 1 == 011000000' – 2013-04-25 22:45:39

+1

)移出時,開始/結束處的位被丟棄。按位操作有點難以解釋。有時候你只需要在調試器下面弄清楚事情的真相,然後看看二進制形式的值來真正理解。 – 2013-04-25 22:48:47

+0

如果mDays等於類似01010101的東西呢?如果你拿00000001並且把它移到00010000,它仍然不會等於01010101(即,00010000!= 01010101),所以它應該返回假,即使第4位都等於1.我錯過了什麼? – MrGibbage 2013-04-26 00:14:52