前面介紹了雪花演算法的理論基礎,可以對大概的演算法有個了解,但是細節上可能還是模糊,下面來說一下雪花演算法中用到的位運算。這裡先介紹兩個,乙個是:
<<
乙個是
|
《的作用是將數字向左移動,這裡的數字指的是二進位制中的數,並不是字面上的長整型數字,當然移動後數字字面值肯定發生變化,但是這裡對這個操作的主要理解要放在二進位制數字向左移動上,而不是字面值擴大2的n次方倍。
「|」 的作用是或運算,兩個數對應的位上只要有乙個是1就是1,這樣的官方解釋不太明顯,放在雪花演算法中的作用就是合併數字,下面會詳細演示。也就是說,三個需要生成的部分,分別由三個數來生成,然後利用 《往左移動到對應的位置,最後將三個數字用 | 合併。這就是雪花演算法中兩個位移操作的作用。
介紹乙個例子比如有三個數字,分別列印出這三個數字的二進位制形式:
可以看到,5對應的二進位制就是101,8對應的2進製就是1000,10對應的二進位制就是1010。這三個數字轉換成二進位制後,所有的0和1自然還是在最右邊的末尾,下面就來進行位移操作a向左移動20位,b向左移動10位,c不變:
通過a和b位移結果的前後對比,可以發現在二進位制的形式下,位移操作的意義淺顯易懂,就是把代表值的所有數字向左移動了對應的位數。我們把雪花演算法生成的數字也分成了三部分,這三部分可以分別按照規則生成,然後用《操作向左移動對應的位數,就可以到達對應的位置,最後再合併即可。
來看一下合併的**:
上面的「a|b|c」操作就是合併三個數字,怎麼合併呢?就是多個64位的數字對應的合在一起,在這64中,只要對應位數上有乙個位置是1,合併後這個位上的數字就是1,否則就是0,根據這個結果,我們看到數字d的二進位制形式確實包含了abc三個的所有數字。雖然最後的結果d是乙個難以猜到的數字,但是我們進行位運算一定要看二進位制,不要看整數字面值,這三個數字放在了各自對應的位數範圍內,只要三個數字的範圍不越界,也就是說a永遠在從右向左20位以後,b永遠在10到20之間,c永遠在0到10之間,那麼這三個數字就可以各管各的,並且結果是合法合理的。
當然這種操作也是有底線的,比如b,他的數字大小轉換成2進製後如果長度比10位大,那麼它就會和a互相影響,導致結果不可預料,這就是範圍的由來。我們再來考慮一下雪花演算法,除了第一位0之外,第一部分是時間部分,佔41位,也就是說生成的時間數字要向左移動(64-1-41=)22位,第二部分是機器資訊,佔10位,也即是說代表機器資訊的數字生成後要向左移動(64-1-41-10=)12位,當然第三部分在末尾,就不用位移了。這三部分計算出來並且向左位移完成後,直接用「|」運算合成即可,就是我們最終要的分布式唯一id。
演算法 位運算
public static intpowern int m,int n return m public static void main string args public static boolean ispower int n return false num如何使2的n次冪,那麼num nu...
基於雪花演算法生成64位ID
import logging import time class generator object 64位id 1 符號位不用 41 毫秒 4 機器id 6 業務編碼 12 重複累加 基礎時間 毫秒 1577808000000 2020 01 01 00 00 最大支援時間差 21990232555...
位運算在演算法中的應用
leetcode原題位址 題目描述 給定乙個整數,編寫乙個函式來判斷它是否是 2 的冪次方。解法 n n 將除最後一位的1之外的所有的數字置為0 因為 n n 1,所以n n n n 1 例如 7對應的二進位制為0111 7對應的二進位制為1001 7 7 0001 實現 public boolea...