I have the following variable:
const input = [0x0001000200030004]
And I have a function to unpack four numbers from 1 (it cames from a C++ code, where I have four int16_t that are packed into a single uint64_t)
export function unpack(input: number[]) {
const output: number[] = []
for (const packed of input) {
for (let i = 0; i < 4; i++) {
const num = (packed >> (i * 16)) & 0xffff
const signedNum = num < 0x8000 ? num : -(0x10000 - num)
output.push(signedNum)
}
}
return output
}
The function kind works; however, it is out of order.
Instead of the output being [1, 2, 3, 4], it is [1, 2, 4, 3].
What I’m doing wrong?
2
Answers
The issue is that bitwise operators convert their operands to 32-bit integers first (unless working with
BigInt
s). But0x0001000200030004
cannot be represented using 32 bits, so the code does not work properly. The solution is to simply useBigInt
s for all operations instead.You would also need to reverse the order of iteration or reverse the output at the end to get the most significant digits first.
The issue has already been identified in the comments and in @Unmitigated’s answer (namely that bitwise operators work on 32 bit numbers in JS, which cannot represent your uint64), but a better solution is to use a
BigUint64Array
and aInt16Array
as views on the same buffer for the conversion:However, you might need a
DataView
to control endianness, which might be different than the one of the platform where your C++ code is executed.