您好,登錄后才能下訂單哦!
本篇內容介紹了“java雪花算法中的運算符舉例分析”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
雪花算法已經初步完成了。現在我們再來看幾個位操作。先看第一個,還是左移操作,不過這里演示負數左移:
<<
看這個之前,我們先看一個關鍵的數字,最大的負整數,-1L轉換為二進制后的形式:
這里注意二進制數字的思路是相反的,在負整數中,除去負號外,那個數字越大,這個負數就越小,在Java的二進制形式中,首位代表正負號,除去首位,剩下的數字值越大,真的就代表數字本身越大,無論正負。從上面打印可以看出,-1L的二進制形式就是一個最大負整數。
我們前面討論位運算提到過左移運算 << ,那么負數左移會出現什么情況的呢?下面來看一個例子:
從字面值上來看,負整數左移和正整數左移效果是一樣的,就是把字面值變小了,二進制的形式也能看出,所有的1左移后,右面直接補0,效果也是把數字變小了。
前面我們說過兩個位移操作,那兩個我們主要是關注二進制形式的數字效果,這里我們就要看字面值的變化了。-1L向左位移1位,字面值就變成
-1L * 2^1
如果向左位移n位,字面值就會變成:
-1L * 2^n
這就是-1L向左位移的字面值變化規律。
看完負數左移操作,再來看一個位移操作,取反操作:
~
取反的意思也是針對二進制形式的數字說的,因為所有位上的數字不是0就是1,所以取反的操作就是把0變成1,把1變成0,來看幾個例子:
上面的正整數3L,取反后,字面值變成了-4L,二進制的數字中的0和1也徹底反了,0變成1,1變成0。而負整數-9L字面值變成了8L,二進制數字的變化也是一樣的規律。大家可以多試幾次,從上面的內容可以總結出取反的規律:
1、取反后,正整數變成了負整數,負整數變成了正整數 2、取反后,無論原來是正數還是負數,結果都會變成 (n+1) * -1L
取反操作我們也不看二進制數字的變化,但看字面值的變化,可以總結出上面的規律。
現在有個需求,如果有三位二進制數,那么能表示的最大正數就是 111,也就是7,如果有四位就是1111,也就是15,如果有n位如何用位運算表示?其實公式很容易推出來,就是
2^n-1
這個公式和上面的負數左移很相似,我們來使用-1L進行左移:
-1L << n
這樣n如果是3和4就分別對應-8L和-16L,從字面值上看和我們的需求很接近,我們再來進行取反操作:
~(-1L << n)
這樣3和4分別對應的就是7和15了!上面這個位運算公式,就是求出n位二進制數能表示的最大整數的公式!
再來看雪花算法中的限制,數據中心id和機器id分別占5位,最大數都是31,毫秒內序列占12位,最大值是4095,這個值直接定義上是最快的,現在也可以用高效的位運算計算出來了:
雪花算法的毫秒內序列有兩個操作,一個是在同一毫秒內加一,另一個是如果超過最大值,就強制等到下一個不同的時間從新開始序列。這里也是可以用位操作實現的。這里首先討論下面的位操作:
&
這個操作的意思是同一個位上,都是1,結果才是1,否則就是0.下面用二進制數字演示一下:
15L 轉換為2進制形式后有個特點,就是前面所有位上都是1,那么這個時候,其實較小的數是多少結果就是多少。從而可以推理出,只要較大的數有這個特點,那么&操作的結果都和較小的數的值一樣。如果超過最大值會怎么樣呢?
可以看到,只要超過1,那么結果就會歸0,再加上1, 15L & 17L的話,結果又會是1。這樣的&操作可以防止數字超過某個最大限制。這種特性正好用在毫秒內序列的加一操作上。
seq = (seq + 1) & 4095;
像上面那種寫法,其實最終值和
seq = seq + 1
效果是一樣的,不同的是,一旦超過了4095,seq會從新變成0。
“java雪花算法中的運算符舉例分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。