int64-buffer
int64-buffer copied to clipboard
Add support for the new BigInt type introduced in Node 10.7.0
Now that there is a native BigInt type, it should be used by this library when available. Right now it's only a few times faster, but future optimizations should make it a lot faster. BigInt64Array and BigUint64Array can be used for buffering.
https://github.com/tc39/proposal-bigint
I've tried some basic BigInt manipulations:
// Number to BigInt
BigInt(1); // => 1n
// BigInt to Number
Number(1n); // => 1
// typeof
"bigint" === typeof BigInt(1); // => true
// BigInt (or Number) to String
(9007199254740993n).toString(); // => "9007199254740993" (correct)
(9007199254740993).toString(); // => "9007199254740992" (wrong)
// String to BigInt (or Number)
BigInt("9007199254740993"); // => 9007199254740993n (correct)
Number("9007199254740993"); // => 9007199254740992 (wrong)
// read BigInt value from ArrayBuffer
ab = Uint8Array.from([1,0,0,0,0,0,0,0]).buffer;
new BigUint64Array(ab)[0]; // => 1n
new DataView(ab).getBigUint64(0, true); // => 1n
// write BigInt value on ArrayBuffer
ab = Uint8Array.from([1,0,0,0,0,0,0,0]).buffer;
new BigUint64Array(ab)[0] = 2; // TypeError: Cannot convert 2 to a BigInt
new BigUint64Array(ab)[0] = 3n; // OK
new DataView(ab).setBigUint64(0, 4, true); // TypeError: Cannot convert 4 to a BigInt
new DataView(ab).setBigUint64(0, 5n, true); // OK
It looks that BitInt/BigInt64Array spec proposal on stage 3 has pretty limited features. We could add the pair of input / output interface for the library to support BigInt at least:
// current interface
var big = new Uint64BE("9007199254740993");
big.toNumber(); // => 9007199254740992 (wrong)
big.toString(); // => "9007199254740993" (correct)
// additional interface (proposal)
var big = new Uint64BE(9007199254740993n);
big.toBigInt(); // => 9007199254740993n (correct)
This is great because it does not break any bits than 2^53.
I guess, however, the library's internal buffer structure should remain with Uint8Array still and not to be changed for backward compatibility reasons.
This makes me realize that this should actually be split into 2 distinct issues:
- Support for input/output of BigInt.
- Internal representation as BigInt.
I definitely agree that it makes a lot more sense to only do the first issue at this point since BigInt has not been optimized yet in V8, meaning the current implementation of this library is probably faster at the moment.
When it does get optimized, however, I think the second point should be addressed as well. I agree that backward compatibility could be an issue, so this could be configurable. Another option would be to create a new library that can use either int64-buffer or BigInt depending on the Node version and only supports a subset of functionality that works the same for both.
I've pushed 92861a16b with basic input/output support at the bigint branch.
The current version of TypeScript 3.1 does not support BigInt yet by the way. int64-buffer.d.ts needs TypeScript 3.2 (November 2018) which will support it.
https://github.com/Microsoft/TypeScript/wiki/Roadmap#32-november-2018
I would assume that supporting BigInt is the good time to release version 1.0.0 of the library.
Thanks!
This looks good so far, but will this allow for things like CRC64 hashing support when complete?
https://nodejs.org/en/blog/release/v12.0.0/ Node.js 12.0.0 added {read|write}Big[U]Int64{BE|LE} methods.
It can be used in a similar way to int64-buffer.
const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]);
console.log(buf.readBigUInt64BE(0));
// Prints: 4294967295n
console.log(buf.readBigUInt64LE(0));
// Prints: 18446744069414584320n