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?
>Solution :
The issue is that bitwise operators convert their operands to 32-bit integers first (unless working with BigInt
s). But 0x0001000200030004
cannot be represented using 32 bits, so the code does not work properly. The solution is to simply use BigInt
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.
function unpack(input) {
const output = [];
for (const packed of input) {
for (let i = 3n; i >= 0n; i--) {
const num = (packed >> (i * 16n)) & 0xffffn;
const signedNum = num < 0x8000n ? num : -(0x10000n - num);
output.push(signedNum);
}
}
return output;
}
console.log(unpack([0x0001000200030004n]).map(x => x.toString()));