使用Node.js進行32位元的整數運算


JavaScript的Number採用64位元的IEEE 754標準來表示整數和浮點數數值,其中整數的安全範圍在-253 - 1到253 - 1之間。換句話說,Node.js既不能直接使用到32位元的整數,同時也無法使用64位元的整數。因此,如果要拿Node.js來做一些稍微複雜的計算,就需要撰寫額外的程式來處理資料型態的部份。像是32位元整數經常會遇到的「溢位」,想要在Node.js上重現就比較麻煩。

以下C語言程式示範了32位元的整數遇到溢位的情形:

輸出結果為:

-2

32位元的整數所能表示的最大值為231 - 1 = 214748364710 = 011111111111111111111111111111112。程式第5行宣告了變數a。並指派了一個最大值給變數a儲存。接著在程式第6行讓a儲存的數值乘2了。如果熟悉位元運算的話,可以很快地將「乘2」這個動作對應成向左位移1個位元,也就是說「111111111111111111111111111111112」向左位移1個位元之後,原本在最左邊的最大位元(MSB)「0」會因為左移而被移除,而最小位元(LSB)會被填上0,所以位移後最終的數值是「111111111111111111111111111111102」。由於有號數是使用2的補數來表示,因此「111111111111111111111111111111102」換算成10進制數值後會是「-210」。若要使用JavaScript來得到像上述這樣進行乘法計算卻遇到溢位又要考慮補數的結果,可以利用Math所提供的「imul」函數來完成。

輸出結果為:

-2

然而網路上還流傳著一種做法,那就是將最後的運算結果去OR一個0。程式如下:

輸出結果為:

-2

這裡必須要注意到的是,「將最後的運算結果去OR一個0」雖然在上面的範例中算出來的答案和Math所提供的「imul」函數相同,但它並不是一個正確的32位元整數的解決方案,因為它在很多情況下算出來的答案不是對的。舉例:

輸出結果為:

675192498
675192448

使用以下C程式來驗證結果:

輸出結果為:

675192498

既然JavaScript可以直接使用Math所提供的「imul」函數來模擬32位元整數的乘法,想必加、減、除也有對應的函數囉?很遺憾,加、減、除法並沒有這樣的函數可以使用,所以說在JavaScript上要進行32位元整數運算是一件麻煩的事情。利用基於C/C++語言的N-API來實作32位元整數運算才會容易許多。

int32

int32」是一個使用Node.js 8之後才支援的N-API所開發的模組,使用C語言原生的「int32_t」型態來直接進行32位元的整數運算。

GitHub:

https://github.com/magiclen/node-int32

npm:

https://www.npmjs.com/package/int32

安裝

直接使用npm指令進行安裝:

npm install --save int32

用法

初始化

使用「require」函數來引入「int32」模組。利用模組的「Int32」屬性可取得「Int32」物件的建構子。

靜態函數的用法
add

subtract

multiply

divide

shiftLeft

shiftRight

shiftRightUnsigned

rotateRight

rotateLeft

operate

物件方法的用法
建立物件實體

物件方法

物件方法的種類和靜態函數大致相同,請參考以下範例:

關於作者

Magic Len

Magic Len

各位好,我是Magic Len,是這網站的管理員。我是台灣台中大肚山上人,畢業於台中高工資訊科和台灣科技大學資訊工程系,曾在桃機航警局服役。我熱愛自然也熱愛科學,喜歡和別人分享自己的知識與經驗。如果你有興趣認識我,可以加我的Facebook,並且請註明是從MagicLen來的。

相關文章