Как в Javascript (но не в узле) разделить два массива Uint8Array?

Я использую встроенный в браузер 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 меня устраивает.


person satish    schedule 05.06.2018    source источник
comment
Если каждый элемент в вашей области представляет собой «место» в числе, ваше первое число намного больше, чем 0xffffffff. Это 256 ** 8. если я не понимаю, как вы переходите от массива к целому числу.   -  person Mark    schedule 05.06.2018
comment
кстати 8 байт = 2^64 = 18446744073709552000 › Number.MAX_SAFE_INTEGER = 9007199254740991   -  person Michał Z.    schedule 05.06.2018
comment
Используйте большую целочисленную библиотеку. Хороший должен поддерживать Uint8Arrays в качестве входных и выходных данных.   -  person Bergi    schedule 05.06.2018


Ответы (2)


Существует библиотека, которую вы можете использовать для вызова BigInteger. /большое целое

Я не видел встроенного способа использования 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>

person Keith    schedule 05.06.2018
comment
Спасибо. быстрое продолжение вашей функции buf2hex. У меня есть эта строка -- var bd1 = bigInt(buf2hex(new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]), 16)); но это приводит к ошибке Error: Invalid integer: ffffffffffffffffff. Что мне не хватает? - person satish; 06.06.2018
comment
У тебя скобки не в том месте. -› 255]), 16)); должно быть 255])), 16); - person Keith; 06.06.2018
comment
Ах, моя ошибка! Спасибо, - - person satish; 06.06.2018

Хотя максимальное число будет:

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

person Michał Z.    schedule 05.06.2018
comment
8 байт, 64 бита без знака = 18446744073709551615 - person Keith; 06.06.2018
comment
Да, вероятно, ошибка, потому что я проверил это на JavaScript, и поэтому небезопасно использовать числа больше MAX_SAFE_INTEGER, я исправлю свой ответ, спасибо :) - person Michał Z.; 06.06.2018
comment
Первое жирное число, которое у вас есть, это 2 ^ 64-1, а не 2 ^ 64. Максимальное безопасное целое число равно 2 ^ 53-1 из-за формата чисел с плавающей запятой двойной точности, если вы не знали. - person Patrick Roberts; 06.06.2018
comment
Спасибо, исправлено :) Да, если это целое число превышает байты - оно становится числом с плавающей запятой - person Michał Z.; 06.06.2018