7

I'm using in-browser Javascript, not NodeJS. I have two Uint8Arrays ...

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

Each will have exactly 8 elements that are whole numbers between 0 and 255. Each array represents a larger number. For example, the first array represents the positive integer

0xffffffff

My question is how can I divide d1 by d2 and get a result? I read that the maximum value for an integer in Javascript is 2^53, which I believe less than the maximum number I could have. I don't care what the object type the result is, but Uint8Array is fine by me.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
satish
  • 703
  • 5
  • 23
  • 52
  • If each item in your area represents a 'place' in the number, your first number is much larger than 0xffffffff. It's `256 ** 8`. unless I'm misunderstanding how you are getting from the array to an integer. – Mark Jun 05 '18 at 20:36
  • btw 8 bytes = 2^64 = **18446744073709552000** > Number.MAX_SAFE_INTEGER = **9007199254740991** – Michał Z. Jun 05 '18 at 20:41
  • Use a big integer library. A good one should support Uint8Arrays as in- and outputs. – Bergi Jun 05 '18 at 20:53

2 Answers2

2

There is a library you can use call BigInteger.. https://www.npmjs.com/package/big-integer

I didn't see a built in way to use Uint8Array, but I found this -> Javascript ArrayBuffer to Hex that had a way to convert into hex, that bigInteger seems ok with.

So here is an example of using it. ->

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>
Keith
  • 22,005
  • 2
  • 27
  • 44
  • Thanks. quick follow up on your buf2hex function. I have this line -- "var bd1 = bigInt(buf2hex(new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]), 16));" but its resulting in an "Error: Invalid integer: ffffffffffffffff" error. What am I missing? – satish Jun 05 '18 at 21:59
  • You have you brackets in the wrong place. -> `255]), 16));` should be `255])), 16);` – Keith Jun 05 '18 at 22:02
  • Ah my mistake! Thanks, - – satish Jun 05 '18 at 22:04
1

Although max number would be:

8 bytes = 2^64-1 = 18446744073709551615 (check 2**64 in browser - the result will be different!)

which is greater than maximum safe integer:

Number.MAX_SAFE_INTEGER = 9007199254740991


I would try anyway something like this:

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);

EDIT

The results are obviously wrong if you are above Number.MAX_SAFE_INTEGER

Michał Z.
  • 1,322
  • 1
  • 10
  • 17
  • 1
    8 bytes, unsigned 64bit = 18446744073709551615 – Keith Jun 05 '18 at 22:12
  • Yeah, probably mistake because I checked that on JavaScript and that's why it's unsafe to use numbers greater than MAX_SAFE_INTEGER, I'll fix my answer, thanks:) – Michał Z. Jun 06 '18 at 05:01
  • 1
    The first bold number you have is 2^64-1, not 2^64. The max safe integer is 2^53-1 due to the format of double precision floating point numbers, in case you didn't know. – Patrick Roberts Jun 06 '18 at 05:06
  • Thanks, fixed:) Yeah, in case that integer number exceedes bytes - it "becomes" floating point number – Michał Z. Jun 06 '18 at 05:12