溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

java雪花算法中的運(yùn)算符舉例分析

發(fā)布時(shí)間:2021-11-16 16:16:49 來源:億速云 閱讀:110 作者:iii 欄目:大數(shù)據(jù)

本篇內(nèi)容介紹了“java雪花算法中的運(yùn)算符舉例分析”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

n位二進(jìn)制表示的最大值

雪花算法已經(jīng)初步完成了。現(xiàn)在我們?cè)賮砜磶讉€(gè)位操作。先看第一個(gè),還是左移操作,不過這里演示負(fù)數(shù)左移:

<<

看這個(gè)之前,我們先看一個(gè)關(guān)鍵的數(shù)字,最大的負(fù)整數(shù),-1L轉(zhuǎn)換為二進(jìn)制后的形式:

java雪花算法中的運(yùn)算符舉例分析

這里注意二進(jìn)制數(shù)字的思路是相反的,在負(fù)整數(shù)中,除去負(fù)號(hào)外,那個(gè)數(shù)字越大,這個(gè)負(fù)數(shù)就越小,在Java的二進(jìn)制形式中,首位代表正負(fù)號(hào),除去首位,剩下的數(shù)字值越大,真的就代表數(shù)字本身越大,無論正負(fù)。從上面打印可以看出,-1L的二進(jìn)制形式就是一個(gè)最大負(fù)整數(shù)。

我們前面討論位運(yùn)算提到過左移運(yùn)算 << ,那么負(fù)數(shù)左移會(huì)出現(xiàn)什么情況的呢?下面來看一個(gè)例子:

java雪花算法中的運(yùn)算符舉例分析

從字面值上來看,負(fù)整數(shù)左移和正整數(shù)左移效果是一樣的,就是把字面值變小了,二進(jìn)制的形式也能看出,所有的1左移后,右面直接補(bǔ)0,效果也是把數(shù)字變小了。

前面我們說過兩個(gè)位移操作,那兩個(gè)我們主要是關(guān)注二進(jìn)制形式的數(shù)字效果,這里我們就要看字面值的變化了。-1L向左位移1位,字面值就變成

-1L * 2^1

如果向左位移n位,字面值就會(huì)變成:

-1L * 2^n

這就是-1L向左位移的字面值變化規(guī)律。

看完負(fù)數(shù)左移操作,再來看一個(gè)位移操作,取反操作:

~

取反的意思也是針對(duì)二進(jìn)制形式的數(shù)字說的,因?yàn)樗形簧系臄?shù)字不是0就是1,所以取反的操作就是把0變成1,把1變成0,來看幾個(gè)例子:

java雪花算法中的運(yùn)算符舉例分析

上面的正整數(shù)3L,取反后,字面值變成了-4L,二進(jìn)制的數(shù)字中的0和1也徹底反了,0變成1,1變成0。而負(fù)整數(shù)-9L字面值變成了8L,二進(jìn)制數(shù)字的變化也是一樣的規(guī)律。大家可以多試幾次,從上面的內(nèi)容可以總結(jié)出取反的規(guī)律:

1、取反后,正整數(shù)變成了負(fù)整數(shù),負(fù)整數(shù)變成了正整數(shù)

2、取反后,無論原來是正數(shù)還是負(fù)數(shù),結(jié)果都會(huì)變成   (n+1) * -1L

取反操作我們也不看二進(jìn)制數(shù)字的變化,但看字面值的變化,可以總結(jié)出上面的規(guī)律。

現(xiàn)在有個(gè)需求,如果有三位二進(jìn)制數(shù),那么能表示的最大正數(shù)就是 111,也就是7,如果有四位就是1111,也就是15,如果有n位如何用位運(yùn)算表示?其實(shí)公式很容易推出來,就是

2^n-1

這個(gè)公式和上面的負(fù)數(shù)左移很相似,我們來使用-1L進(jìn)行左移:

-1L << n

這樣n如果是3和4就分別對(duì)應(yīng)-8L和-16L,從字面值上看和我們的需求很接近,我們?cè)賮磉M(jìn)行取反操作:

~(-1L << n)

這樣3和4分別對(duì)應(yīng)的就是7和15了!上面這個(gè)位運(yùn)算公式,就是求出n位二進(jìn)制數(shù)能表示的最大整數(shù)的公式!

再來看雪花算法中的限制,數(shù)據(jù)中心id和機(jī)器id分別占5位,最大數(shù)都是31,毫秒內(nèi)序列占12位,最大值是4095,這個(gè)值直接定義上是最快的,現(xiàn)在也可以用高效的位運(yùn)算計(jì)算出來了:

java雪花算法中的運(yùn)算符舉例分析

不超過最大值的序列遞增

雪花算法的毫秒內(nèi)序列有兩個(gè)操作,一個(gè)是在同一毫秒內(nèi)加一,另一個(gè)是如果超過最大值,就強(qiáng)制等到下一個(gè)不同的時(shí)間從新開始序列。這里也是可以用位操作實(shí)現(xiàn)的。這里首先討論下面的位操作:

&

這個(gè)操作的意思是同一個(gè)位上,都是1,結(jié)果才是1,否則就是0.下面用二進(jìn)制數(shù)字演示一下:

java雪花算法中的運(yùn)算符舉例分析

15L 轉(zhuǎn)換為2進(jìn)制形式后有個(gè)特點(diǎn),就是前面所有位上都是1,那么這個(gè)時(shí)候,其實(shí)較小的數(shù)是多少結(jié)果就是多少。從而可以推理出,只要較大的數(shù)有這個(gè)特點(diǎn),那么&操作的結(jié)果都和較小的數(shù)的值一樣。如果超過最大值會(huì)怎么樣呢?

java雪花算法中的運(yùn)算符舉例分析

可以看到,只要超過1,那么結(jié)果就會(huì)歸0,再加上1, 15L & 17L的話,結(jié)果又會(huì)是1。這樣的&操作可以防止數(shù)字超過某個(gè)最大限制。這種特性正好用在毫秒內(nèi)序列的加一操作上。

seq = (seq + 1) & 4095;

像上面那種寫法,其實(shí)最終值和

seq = seq + 1

效果是一樣的,不同的是,一旦超過了4095,seq會(huì)從新變成0。

“java雪花算法中的運(yùn)算符舉例分析”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI