1. 程式人生 > >位與運算與取餘

位與運算與取餘

關於位與運算&與取餘
今天在研究hashmap原始碼的時候,發現其原始碼中在解決Entry分佈時,本來大多數人以為會用index = hash % length,但是原始碼中卻使用了index = hash & (lenth -1)的方式。

/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

  

另外由上述還可以注意到,在原始碼中對於Entry陣列容量的定義中,要求容量必須為2的n次冪(或0),於是就搜尋查詢了一下用意。

原來位與也是可以用來取餘的,但是有一個條件:除數必須是2的n次冪才行。舉例子來說明:

9%8=1
1001 & (1000 - 1=1001 & 0111
=1 // 1001是9的二進位制表示,1000是8的二進位制表示

 

其實很明顯了,在二進位制計算中,眾所周知的是,一個數右移1位相當於除以2的商,而恰巧被移除出去的那一位就是除以2得到的餘數,例如:

9 >> 1
=1001 >> 1
=100 | 1
=4 餘 1

 

而且,不僅是除以2,對於一個數k要除以2的n次方,也就是相當於把k向右移n位,而被移出去的n位即正好是我們要求是餘數。

那麼問題就簡單了,實際上,對於除數是2的n次方的算式,我們只需要得到被除數的低n位就可以了,而正好,對於2的n次方這樣的數,我們將其轉換為二進位制之後,它就是第n+1位為1,其餘低位都為0的數,因此我們將其減1,就得到了第n+1位為0,而其他位都為1的數,用此數與被除數k進行位與運算,就得到了被除數的低n位二進位制數,也即是
k%2n的結果。


總結:
若一個數m滿足: m=2n

那麼k % m = k & (m-1)