我有一个 Javascript 整数(其精度可以达到
2^53 - 1
),我正在尝试使用 ArrayBuffer
通过网络发送它。我想我可以使用 BigInt64Array
,但浏览器支持似乎仍然相对较新。
我不能使用
Int32Array
(这是我最初的解决方案),因为它的精度最高可达2^32 - 1
,而Javascript整数可以安全地达到2^53 - 1
。这是我的问题。
有没有一种简单的方法可以将任意 Javascript 整数转换为长度为 8 的
Uint8Array
?
例如,我正在寻找这样的函数:
function numToUint8Array(num) {
let arr = new Uint8Array(8);
// fill arr values with that of num
return arr;
}
let foo = numToUint8Array(9458239048);
let bar = uint8ArrayToNum(foo); // 9458239048
标准库中已经存在这样的东西了吗?如果没有的话有没有办法写这样的东西?
@Bergi,你想到的是这样的吗?
function numToUint8Array(num) {
let arr = new Uint8Array(8);
for (let i = 0; i < 8; i++) {
arr[i] = num % 256;
num = Math.floor(num / 256);
}
return arr;
}
function uint8ArrayToNumV1(arr) {
let num = 0;
for (let i = 0; i < 8; i++) {
num += Math.pow(256, i) * arr[i];
}
return num;
}
function uint8ArrayToNumV2(arr) {
let num = 0;
for (let i = 7; i >= 0; i--) {
num = num * 256 + arr[i];
}
return num;
}
let foo = numToUint8Array(9458239048);
let bar = uint8ArrayToNumV1(foo); // 9458239048
let baz = uint8ArrayToNumV2(foo); // 9458239048
console.log(foo, bar, baz);
如果你不想使用Math类,你可以使用这个脚本:
function numToUint8Array(num) {
const arr = new Uint8Array(8);
for(let i = 0; i < 8; i++)
arr.set([num/0x100**i], 7-i)
return arr;
}
function uint8ArrayToNum(arr) {
let num = 0;
for(let i = 0; i < 8; i++)
num += (0x100**i) * arr[7-i];
return num;
}
测试代码:
const arr = numToUint8Array(257);
console.log(arr);
const num = uint8ArrayToNum(arr);
console.log(num);
结果:
Uint8Array(8) [
0, 0, 0, 0,
0, 0, 1, 1
]
257
这是我目前喜欢使用的解决方案
// BigInt to Uint8Array
myBigInt = 123456789n;
dv = new DataView(new ArrayBuffer(8), 0);
dv.setBigUint64(0, myBigInt);
uArr = new Uint8Array(dv.buffer);
console.debug('Uint8Array', uArr);
// Uint8Array to BigInt
bytesArr = new Uint8Array([0, 0, 0, 0, 7, 91, 205, 22]);
dv = new DataView(bytesArr.buffer, 0);
myBigInt = dv.getBigUint64();
console.debug('BigInt', myBigInt);