在Javascript中(但不包括Node),如何将两个Uint8Array相除?

7

我正在使用浏览器内置的Javascript,而不是NodeJS。我有两个Uint8Array数组...

var d1 = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255])
var d2 = new Uint8Array([255, 255, 255, 255, 237, 49, 56, 0])

每个数组都有8个元素,这些元素是0到255之间的整数。每个数组代表一个更大的数字。例如,第一个数组代表正整数。
0xffffffff

我的问题是如何将d1除以d2并得到结果?我了解到在Javascript中整数的最大值是2^53,这个值比我可能拥有的最大值要小。我不关心结果的对象类型,但Uint8Array对我来说是可以接受的。


如果您的数组中每个项表示数字中的一个“位置”,那么您的第一个数字要比0xffffffff大得多,它是“256 ** 8”。除非我误解了您如何从数组转换为整数。 - Mark
顺便提一下,8个字节等于2^64 = 18446744073709552000。而Number.MAX_SAFE_INTEGER = 9007199254740991。 - Michał Z.
使用一个大整数库。一个好的库应该支持Uint8Arrays作为输入和输出。 - Bergi
2个回答

2

有一个库可以使用,叫做BigInteger。https://www.npmjs.com/package/big-integer

我没有看到内置的方法可以使用Uint8Array,但是我找到了这个 -> Javascript ArrayBuffer to Hex 它提供了一种将其转换为十六进制的方法,bigInteger似乎可以接受。

所以这里是一个使用它的例子。->

var d1 = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]);
var d2 = new Uint8Array([255, 255, 255, 255, 237, 49, 56, 0]);

function buf2hex(buffer) { // buffer is an ArrayBuffer
  return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}

var bd1 = bigInt(buf2hex(d1), 16);
console.log(`value 1 = ${bd1.toString()}`);
var bd2 = bigInt(buf2hex(d2), 16);
console.log(`value 2 = ${bd2.toString()}`);
var r = bd1.divmod(bd2);
console.log(`result ${r.quotient.value} remainder ${r.remainder.value}`);
<script src="https://peterolson.github.io/BigInteger.js/BigInteger.min.js"></script>


谢谢。关于您的buf2hex函数,我有一个快速的跟进。我有这一行代码 - "var bd1 = bigInt(buf2hex(new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]), 16));" 但是它导致了一个"Error: Invalid integer: ffffffffffffffff"错误。我错过了什么? - satish
你的括号放错了位置。255]), 16)); 应该是 255])), 16); - Keith
啊,我的错误!谢谢。- - satish

1

尽管最大数字可能是:

8个字节 = 2^64-1 = 18446744073709551615(在浏览器中检查2 ** 64 - 结果将不同!)

这比最大安全整数还要大:

Number.MAX_SAFE_INTEGER = 9007199254740991


我会尝试像这样做:

var d1 = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]);
var d2 = new Uint8Array([255, 255, 255, 255, 237, 49, 56, 0]);

function decodeInt(uint8a){
    return parseInt('0x'+Array.from(uint8a).map(x=>('0'+x.toString(16)).slice(-2)).join(''));
}

decodeInt(d1) / decodeInt(d2);

编辑

如果您超过Number.MAX_SAFE_INTEGER,结果显然是错误的。


1
8字节,无符号64位 = 18446744073709551615 - Keith
是的,可能是因为我在 JavaScript 上检查了它,所以使用大于 MAX_SAFE_INTEGER 的数字是不安全的。我会修正我的回答,谢谢 :) - Michał Z.
1
你手头的第一个粗体数字是2^64-1,而不是2^64。双精度浮点数的格式限制了最大安全整数为2^53-1,以防你不知道。 - Patrick Roberts
谢谢,已修复 :) 是的,如果整数超过字节 - 它会“变成”浮点数。 - Michał Z.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接