JavaScript的Number採用64位元的IEEE 754標準來表示整數和浮點數數值,其中整數的安全範圍在-253 - 1到253 - 1之間。換句話說,Node.js既不能直接使用到32位元的整數,同時也無法使用64位元的整數。因此,如果要拿Node.js來做一些稍微複雜的計算,就需要撰寫額外的程式來處理資料型態的部份,進而影響到執行效能。



int64-napi

「int64-napi」是一個使用Node.js 8之後才支援的N-API所開發的模組,使用C語言原生的「int64_t」型態來直接進行64位元的整數運算,可以將效能的影響減到最低。

GitHub:

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

npm:

https://www.npmjs.com/package/int64-napi

安裝

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

npm install int64-napi --save

用法

初始化

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

const int64 = require('int64-napi'); // static functions
const Int64 = int64.Int64; // instance methods

「Int64」的實體可以用以下幾種不同的資料來建立:

  • 其它Int64的實體。
  • 兩個整數值,分別代表64位元長整數的低位元和高位元的部份。
  • 一個53位元的整數。
  • 十進制數值的字串。
  • 以「0x」開頭的十六進制數值的字串。
  • 以「0b」開頭的八進制數值的字串。
  • 一個存著8個位元組資料的Buffer。
靜態函數的用法
Random
var n = int64.random('0x1234567800000000', '0x123456780000FFFF'); // 0x123456780000CE74
Add
var n = int64.add('1', 0x00000002, 0x00000000); // 1 + 2 = 3
Subtract
var n = int64.subtract(1, 2); // 1 - 2 = -1
multiply
var n = int64.subtract(2, 6); // 12
divide
var n = int64.divide(6, 4); // 1
mod
var n = int64.mod(6, 4); // 2
shiftLeft
var n = int64.shiftLeft(5, 2); // 20
shiftRight
var n1 = int64.shiftRight(5, 2); // 1
var n2 = int64.shiftRight(6, 1); // 3
var n3 = int64.shiftRight(-5, 1); // -3
shiftRightUnsigned
var n = int64.shiftRightUnsigned(-5, 1); // 9223372036854775805
rotateRight
var n = int64.rotateRight('0x0000000080000100', 16); // 0x0100000000008000
rotateLeft
var n = int64.rotateLeft('0x0080000000000100', 16); // 0x0000000001000080
and
var n = int64.and('0x000000000000FFFF', '0x0123456789ABCDEF'); // 0x000000000000CDEF
or
var n = int64.or('0x0000FFFF0000FFFF', '0xFFFFFFFFFFFF0000'); // 0xFFFFFFFFFFFFFFFF
xor
var n = int64.xor('0x0000FFFF0000FFFF', '0xFFFFFFFFFFFF0000'); // 0xFFFF0000FFFFFFFF
nand
var n = int64.nand('0x000000000000FFFF', '0x0123456789ABCDEF'); // 0xFFFFFFFFFFFF3210
nor
var n = int64.nor('0x0000FFFF0000FFFF', '0xFFFFFFFFFFFF0000'); // 0x0000000000000000
xnor
var n = int64.xnor('0x0000FFFF0000FFFF', '0xFFFFFFFFFFFF0000'); // 0x0000FFFF00000000
not
var n = int64.nor('0x0000FFFF0000FFFF', '0xFFFFFFFFFFFF0000'); // 0x0000000000000000
eq(等於)
var n = int64.eq('0x0000FFFF0000FFFF', '281470681808895'); // true
ne(不等於)
var n = int64.ne('0x0000FFFF0000FFFF', '0x0000FFFF00000000'); // true
gt(大於)
var n = int64.gt('0x0000FFFF0000FFFF', '0x0000FFFF00000000'); // true
gte(大於等於)
var n = int64.gte('0x0000FFFF0000FFFF', '0x0000FFFF00000000'); // true
lt(小於)
var n = int64.lt('0x0000FFFF0000FFFF', '0x0000FFFF0000FFFF'); // false
lte(小於等於)
var n = int64.lte('0x0000FFFF0000FFFF', '0x0000FFFF0000FFFF'); // true
comp(比較)

若第一個參數大於第二個參數,回傳1。
若第一個參數小於第二個參數,回傳-1。
若第一個參數等於第二個參數,回傳0。

var a = int64.comp('0x0000FFFF0000FFFF', '0x0000FFFF0000FFFF'); // 0
var b = int64.comp('0x0000FFFF0000FFFF', '0x0000FFFF00000000'); // 1
var c = int64.comp('0x0000FFFF00000000', '0x0000FFFF0000FFFF'); // -1
物件方法的用法
建立物件實體
var i64 = new Int64(1);

var i64 = int64.from(1);

var i64 = Int64.from(1);
物件方法

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

var n1 = i64.add(1).multiply(3).subtract(3).divide(3).toText(); // 0x0000000000000001
i64.set(0, 0xFFFF0000);
var n2 = i64.shiftLeft(8).shiftRight(56).toText(); // 0xFFFFFFFFFFFFFFFF
i64.set(0, 0xFFFF0000);
var n3 = i64.shiftLeft(8).shiftRightUnsigned(56).toText(); // 0x00000000000000FF
i64.set('0x000000010001');
var n4 = i64.rotateRight(8).toText(); // 0x0100000000000100
i64.set(0xFFFF0000, 0x0000FFFF);
var n5 = i64.getIntValues();  // { low: -65536, high: 65535 }
var n51 = i64.toText(); // 0x0000FFFFFFFF0000
var n52 = i64.toHex(); // 0000ffffffff0000
var n53 = i64.toString() + 1; // 2814749766451201
var n54 = i64.toNumber() + 1; // 281474976645121