JavaScript: чтение от 8 до 64 бит

У меня есть буферный объект, содержащий восемь байтов. Эти восемь байтов теперь должны интерпретироваться как 64-битное целое число.

В настоящее время я использую следующий алгоритм:

var int = buff[0];

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

console.log(int);

Это работает, но я считаю, что есть лучшие способы (возможно, использование Uint64Array).

К сожалению, я не могу найти, как Uint16Array может помочь мне здесь.

Привет

Update:

// puts two 32bit integers to one 64bit integer
var bufInt = (buf.readUInt32BE(0) << 8) + buf.readUInt32BE(4);

Ответ 1

Javascript не поддерживает 64-битные целые числа, поскольку собственный тип номера является 64-битным двойным, давая только 53 бита целочисленного диапазона.

Вы можете создавать массивы 32-разрядных чисел (т.е. Uint32Array), но если бы была 64-разрядная версия, то не было бы возможности копировать значения из нее в автономные переменные.

Ответ 2

Вы можете использовать node-int64 для поддержки 64-разрядного целого числа:

var Int64 = require('node-int64');
var int64 = new Int64(buff);

Ответ 3

Есть несколько модулей для обеспечения 64-битной целочисленной поддержки:

Возможно, ваша проблема может быть решена с использованием одной из этих библиотек.

Ответ 4

Жаль, правильный ответ в том, что Javascript не поддерживает 64-битные целые числа (до сих пор).

Таким образом, попытка получить точное 64-битное целое число, сохраненное в ваших 8 байтах, в одну переменную типа JS будет терпеть неудачу. Так или иначе.

Некоторые решения:

  • Точные биты от 0 до 52:

Если вам не нужны верхние 11 бит 64-битного кода, и вам достаточно иметь дело с точными 53-битными целыми числами, вы можете использовать этот способ:

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

(отредактированный вопрос)

  1. "64bit" int с возможными свободными от младших 11-разрядных правильных состояний:

В противном случае, если вам нужно "общее большое значение" 64 бит, и вы не интересуетесь точными значениями до 11 младших бит (самые правые 2-3 цифры огромного 64-битного значения), вы можете использовать этот способ:

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

Для тех, кто интересуется int64 (поддержка 64-битных целых чисел) в Javascript, BEWARE!

Облик:

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)