JS如何處理超過32位的整數的位運算

2021-08-25 17:23:32 字數 1734 閱讀 9897

這個問題是已經畢業的學員李佳問到的,本想在網上查一下給他個答案省事.轉念一想,如果網上如果他能在網上查到看的明白的方案應該不至於來問我.索性自己給他解一解.因為貌似這個問題還是有點意思的.

首先,要知道為什麼這個問題會成為乙個問題.這裡就不得不說說js當中坑爹的位運算規則.

我們知道js是一種弱型別的指令碼語言,所有的數值無論是整數還是小數,其實都是按照64為位的浮點形式儲存.然而當兩個整數在進行位運算時,卻又會自動轉化為32位的有符號整數.這才導致了這個蛋疼的問題.

解決這個問題以前我們先來考慮這樣一件事情,如果在你面前有一缸水,但是你只有乙個32l的桶,現在你想取50l水,要怎樣取. 跑兩趟,對嗎?兩趟不行,三趟種可以吧.

計算機是為人類服務的,這種思路一定可以行的通.

比如現在有乙個超級大的數,我們假定它是0xf ffff ffff,好了九個f夠了,超過32位的就行.如果我們要拿著這個數跟0xf000 000f異或.我們希望得到的結果是0x f 0fff fff0對嗎? 可是理想很豐滿,現實卻是殘酷的,因為當你直接拿這兩個數異或之後,發現結果是 0x 0fff fff0, 因為轉化為32位的整數時,那個超標的數的高位元組部分被截掉了,坑爹啊?

回顧我剛才講到的分趟原理, 既然js每次最多只能處理32位的位運算,那麼能不能分段來處理呢?很肯定的告訴你,可以.

那麼接下來的問題就是:

1,分幾段,怎麼分

2,分出來的資料如何處理

3,分段處理的資料如何整合

結合上面的資料來分析,0xf ffff ffff總有效的資料實際上只存在於後面的9個位元組中,而js的位運算最多可以處理4個位元組的資料,只需要將乙個位元組抽離出來單獨處理,剩下的部分作為另一段處理即可.

瀏覽器有問題,已儲存就崩,直接丟**了

var longn = 0xfffffffff;  //超長數

var shortn = 0x0ffffff0; //標準數

var tool = 0x000000ff; //用於擷取指定位置(最低位位元組)資料的工具數

var t_long = longn & tool; //儲存超長數最低位元組資料

var t_short = shortn & tool; //儲存標準書最低位元組資料

var t_r = t_long ^ t_short; //儲存最低位元組資料異或結果

var offset = math.pow(2,tool.tostring(16).length * 4);

longn = math.floor(longn / offset); //將超長數已處理的資料部分移出,目的是將32位以外的那乙個位元組移進來

//!!!注意,這裡不要使用parseint,因為會使64位轉為32位

shortn = math.floor(shortn / offset); //同上

var t_h = longn ^ shortn; //儲存剩餘未處理的資料異或的結果

t_h *= offset; //將結果左移回到原來的對應位

var result = t_h + t_r //整合結果

console.log(result.tostring(16)); //ff000000f

上面的**只是乙個例子,體現的是一種思路,但還不是乙個完整健壯的解決方案,因為更多位的數上面這個是無法實現的,而且因為32的數是有符號的,所以在分兩段處理時,其中一段最大只能到31位,所以最穩妥的方法應該是根據兩個運算元中長度最大的資料靈活拆分. todo……

Nginx是如何處理請求的

基於命名的虛擬伺服器 name based virtual servers nginx首先要確定由哪個伺服器 server 來處理這個請求,如下面的簡單的例子中,一共有3個虛擬主機,分別是 server 其中 是區分大小寫的正規表示式 為不區分大小寫的正規表示式 為了提高效率,實行嚴格匹配,如果找到...

如何處理人之間的差異

做事要有實事求是的作風。最重要的是,我等要做的事行得通。當要做一件事時,首先在看得是這件事在現實中能不能行得通,能不能帶來好處。當與人打交道時,每個人是不同的,只是不可更改的事實,只必須寬容 理解的。那麼怎麼辦?只要大家在一起能夠把一件事做成,就行了。行得通就行,這就是目標。舉個很簡單的例子 打籃球...

如何處理難以復現的問題

測試過程中經常遇到煩人的事情 今天出現的問題,明天覆現不了 測試環境的問題,開發環境復現不了等等。2.可能需要特定的測試資料 操作步驟 有時問題需要在特定條件下才能出現,問題是伴隨出現的,累積到一定量才起到破壞作用,需要回想一下做了什麼操作 為什麼這樣 兩者有什麼關係,檢視系統日誌,重新進行驗證,找...