5

I have a buffer object which contains eight bytes. These eight bytes should now be interpreted as 64 bit integer.

Currently I use following algorithm:

var int = buff[0];

for (var i = 1; i < buff.length; i++) {
    int += (buff[i] * Math.pow(2, 8 * i));
}

console.log(int);

this works but I believe there are better ways (maybe using Uint64Array).

Unfortunately I cannot find how a Uint16Array could help me here for.

Regards

Update:

// puts two 32bit integers to one 64bit integer
var bufInt = (buf.readUInt32BE(0) << 8) + buf.readUInt32BE(4);
bodokaiser
  • 15,122
  • 22
  • 97
  • 140
  • 1
    what are you trying to do with this 64 bit number? – Alnitak Jan 07 '13 at 16:38
  • When asking the question, you don't really go into what you mean by "better ways", but if you're worried about performance, bit shifting, instead of using Math.Pow might provide some improvement. (Whoops! Apparently not...check the next comment!) – Beska Jan 07 '13 at 16:38
  • 1
    @Beska bit shifting (and bitwise boolean operations) only work with 32 bit range in JS – Alnitak Jan 07 '13 at 16:38
  • 1
    @alnitak Facinating! Okay, well, I'll leave the comment up there, I guess, so others who also may not know it don't fall into the same trap. – Beska Jan 07 '13 at 16:40
  • Okay then I will keep it that way. @Alnitak just some stream parsing ;) – bodokaiser Jan 07 '13 at 16:56

6 Answers6

7

Javascript does not support 64 bit integers, because the native number type is a 64-bit double, giving only 53 bits of integer range.

You can create arrays of 32-bit numbers (i.e. Uint32Array) but if there were a 64-bit version of those there'd be no way to copy values from it into standalone variables.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
4

Since the latest Node.js v12.0.0, you can now use buf.readBigUInt64LE :))

mouse
  • 354
  • 3
  • 9
3

You can use node-int64 for 64-bit integer support:

var Int64 = require('node-int64');
var int64 = new Int64(buff);
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
2

As javascript dont support 64bit integer readily,here is one solution that worked for me.Here i am converting 8 Byte unix timestamp.

inputString = "0000016b40d8ea30"    
var buf = Buffer.from(inputString, 'hex');
timestamp = (parseInt(buf.toString("hex"),16).toString());
console.log(timestamp); //1560161086000
1

For a pity, correct answer is that Javascript not supports 64 bit integers (till now).

So, trying to get exact 64bit integer stored into your 8 bytes into single JS number-type variable will fail. Anyway.

Some decisions:

  1. Exact bits from 0 to 52:

If you do not need upper 11 bits of 64bit and it's enought for you to deal with exact 53-bit integers, you can use this way:

// puts up to 53 bits by 32bit integers to one "64bit" integer
var bufInt = (buf.readUInt32BE(0) & 0x001FFFFF) * 4294967296 + buf.readUInt32BE(4);

(edited question)

  1. "64bit" int with possible loose of low 11 bit correct states:

Otherwise, if you need "common big value" of 64bit and you don't interest about exact values of till 11 low bits (rightmost 2-3 digits of huge 64bit value), you can use this way:

// puts 64 bit value by 32bit integers to one "64bit" integer
// with possible loose of lower 11 bits correctness
var bufInt = buf.readUInt32BE(0) * 4294967296 + buf.readUInt32BE(4);

For those who interest int64 (64 bit integers support) in Javascript, BEWARE!

Look:

var x1 = 1 << 30;
var x2 = 1 << 31;
var x3 = 1 << 32;
var x4 = 1 << 33;
var a = 1240611072103715194;
var b = 1240611072103715193;
var c = 1240611072103700000;
alert(''
    + 'x1=' + x1 + ' (should =1073741824)\n' 
    + 'x2=' + x2 + ' (should =2147483648)\n' 
    + 'x3=' + x3 + ' (should =4294967296)\n' 
    + 'x4=' + x4 + ' (should =8589934592)\n' 
    + 'a=' + a + ' (should =1240611072103715194)\n' 
    + 'a-b=' + (a-b) + ' (should =1)\n'
    + 'a-c=' + (a-c) + ' (should =15194)\n'
);

RESULT:

x1=1073741824 (should =1073741824)
x2=-2147483648 (should =2147483648)
x3=1 (should =4294967296)
x4=2 (should =8589934592)
a=1240611072103715000 (should =1240611072103715194)
a-b=0 (should =1)
a-c=15104 (should =15194)
FlameStorm
  • 944
  • 15
  • 20
0

There are some modules around to provide 64bit integer support:

Maybe your problem can be solved using one of those libraries.

schaermu
  • 13,478
  • 2
  • 39
  • 32