I’m trying to pack a 4 bit (0-15) number, followed by two 10 bit numbers (0-1023), into a UintArray(3)
Such as: 15, 1023, 1023
I am able to read the first 4 bit number, and the last 10 bit number.
But I can’t seem to figure out reading/writing the middle 10 bit number
function writeInt4_10_10(arr, off, a, b, c) {
arr[off + 0] = (a << 4) & 0xf0 | (b >> 4) & 0x0f;
arr[off + 1] = (b << 6) & 0xfc | (c >> 8) & 0x03;
arr[off + 2] = (c << 0) & 0xff;
}
function readInt4_10_10(arr, off) {
var a = (arr[off + 0] & 0xf0) >> 4;
var b = (arr[off + 0] & 0x0f) << 6 | (arr[off + 1] & 0xfc) >> 4;
var c = (arr[off + 1] & 0x03) << 8 | (arr[off + 2] & 0xff) >> 0;
return [a, b, c];
}
var buf = new Uint8Array(3);
writeInt4_10_10(buf, 0, 13, 1001, 999)
var r = readInt4_10_10(buf, 0);
console.log(r)
2
Answers
The writing method has the wrong shift offsets. To get the highest 4 bit of the 10-bit
b
into the lowest 4 bits ofarr[0]
, they need to be shifted by 6. And to get the lowest 6 bit ofb
into the highest 6 bit of the 8-bitarr[1]
, they need be shifted by 2:Notice how the
6
now correspond to the shift in your reading method, where you shift by the same amount just the other direction. However the shift of the lowest 6 bits is mistaken there as well:In short, you need this line in your write routine:
And this line in your read routine:
Putting it all together.
The problem you had is mostly in storing the data at index 1. For your numbers
13, 1001, 999
, we have the following in binary:And to pack into a Uint8Array as you’ve described we need the following arrangement:
So the issue with your code in the write routine is that you shifted
b << 6
without first removing the leading 4 binary digits via a bitmask. 0x3f is the mask you want for that purpose. You only need to shift the result of& 0x3f
by 2 to get those bits in the correct position.For the read routine, you were almost there but you didn’t shift the appropriate amount for
var b
.(arr[off + 1] & 0xfc)
is the right idea, but that mask removes two digits, so you should only shift the result right by 2.