位運算控制數字范圍
通過位運算,可以對一個數進行限制,保證這個數在2n-1(3,7,15,31,63,127,255...)范圍內,當大于指定的數時,會取這個0到2n-1里的某個數,不會讓它溢位,
之前我寫過的位運算的文章
- https://www.cnblogs.com/lori/p/3342781.html
- https://www.cnblogs.com/lori/archive/2013/01/28/2879613.html
- https://www.cnblogs.com/lori/archive/2012/08/10/2631511.html
- https://www.cnblogs.com/lori/archive/2012/06/08/2541399.html
- https://www.cnblogs.com/lori/archive/2012/05/09/2492110.html
本文在ObjectId里的應用
ObjectId最早在mongodb的分布式環境出現,用來生成主鍵,因為mongodb是一個集群的,分布式的,所以要求它的主鍵的要求更高;它主要使用一個12個位元組進行存盤,而我們知道每1個位元組對應8位二進制數,而每4二進制數對應1個16進制數,所以12個位元組用16進制表示,就是24個16進制字符組成,

位運算與實作范圍限制
在使用&與運算時,我們知道它對2^-1有一個定理,16進制就是f,ff,fff,ffff,fffff....這些,它對應的二進制是由N個1組成的,它與其它數字進行與時就有一些特性(全1為1,有0則0),通過這個特性,我們可以限定一個數字范圍,
@Test
public void bitOperator() {
log.info("10 & 7={}", 10 & 7);
log.info("3 & 7={}", 3 & 7);
log.info("10 & 255={}", 10 & 255);
log.info("300 & 255={}", 300 & 255); //255的16進制為ff,后面數字為2^n-1
}
結果

從圖中可以看出,10 & 7中,10大于后面的7,由于使用了&運算,保證了結果在0~7之間;而3 & 7,由于3小于7,所以結果就是3本身,
二進制看個究竟
10對應的二進制1010
7 對應的二進制111
現在進行與運算
1010
&
0111
結果
0010
對應10進行是2,由于7是111組成,而10是1010,當位數不同時,需要為111補0,它就變成了0111,這時,高位由于是0,所以不論你的數有多大,結果都是0,最后也就是0到7之間的某個數了,至于是哪個數,這和你的原數有關,原數高位都是0,低位數字不變,
或運算實作從某個數開始計數
對于或運算,也有它的使用場景,我們以二進制說明,比如0x1000這個數(十進制是4096),其它數與它進行或運算,得到的結果將是從4096開始的數字,如果1 | 4096,結果將是4097,以此類推,不過有一點要注意,你的數字在4096范圍內,它產生與4096作或運算,產生新的數字是不會重復的;但如果你的數字大于4096,比如4097|4096,它的結果將還是4097,這點需要注意,
如果我們確定了數字范圍,可以利用這個性質,在一個較大的數字基礎上,去產生新的數字,
begin = Long.parseLong("1000", 16);
for (int i = 0; i < 10; i++) {
log.info("{} | {} = {}", i, begin, i | begin);//超過begin之后,數字會有重復
}
結果

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/145122.html
標籤:其他
