skip to Main Content

I have a series of numbers that are between 0 and 1023.

And I wanted to see if I could pack them into a single Uint8Array.

And then read them back to their original values.

But I can’t seem to get the logic right.

function writeInt10(arr, off, a, b, c, d)
{
    /*
        a   0, 1
        b   1, 2, 3
        c   3, 4
        d   4, 5
    */
    arr[off+0] = ((a >> 0) & 0xff); 
    arr[off+1] = ((a >> 6) & 0xf) | ((b >> 2) & 0xf);
    arr[off+2] = ((b >> 4) & 0xf) | ((c >> 4) & 0xf);
    arr[off+3] = ((c >> 2) & 0xf) | ((d >> 6) & 0xf);
    arr[off+4] = ((d >> 4) & 0xf);
}
function readInt10(arr, off) {
    var a = arr[off+0] << 0 | arr[off+1] << 2
    var b = arr[off+1] << 6 | arr[off+2] << 4
    var c = arr[off+2] << 0 | arr[off+3] << 8
    var d = arr[off+3] << 0 | arr[off+4] << 8
    
    return [a, b, c, d];
}

var buf = new Uint8Array(5);
var write = writeInt10(buf, 0, 1023, 100, 512, 768)
var read = readInt10(buf, 0)
console.log(read)

2

Answers


  1. Your 0xf masks are wrong. You’ll need 0x3, 0xc, 0xf respectively:

    0xff = 0b11111111
    0xfc = 0b11111100
    0xf0 = 0b11110000
    0xc0 = 0b11000000
    0x00 = 0b00000000
    0x03 = 0b00000011
    0x0f = 0b00001111
    0x3f = 0b00001111
    0x3f = 0b00111111
    

    Also you didn’t apply any bitmasks in readInt10, and I think your offsets are wrong (or I didn’t understand your pattern, as you somehow spread b across 3 bytes). Here’s how I’d do it:

    function writeInt10(arr, off, a, b, c, d) {
        /* 0b aaaa aaaa aabb bbbb bbbb cccc cccc ccdd dddd dddd
        a: 0x    F    F    C    0    0    0    0    0    0    0 
        b: 0x    0    0    3    F    F    0    0    0    0    0 
        c: 0x    0    0    0    0    0    F    F    C    0    0
        d: 0x    0    0    0    0    0    0    0    3    F    F
        */
        arr[off+0] = (a >> 2) & 0xff;                   //                    (a & 0x3fc) >> 2
        arr[off+1] = (a << 6) & 0xc0 | (b >> 4) & 0x3f; // (a & 0x003) << 6 | (b & 0x3f0) >> 4
        arr[off+2] = (b << 4) & 0xf0 | (c >> 6) & 0x0f; // (b & 0x00f) << 4 | (c & 0x3c0) >> 6
        arr[off+3] = (c << 2) & 0xfc | (d >> 8) & 0x03; // (c & 0x03f) << 2 | (d & 0x300) >> 8
        arr[off+4] = (d << 0) & 0xff;                   // (d & 0x0ff) << 0
    }
    function readInt10(arr, off) {
        var a = (arr[off+0] & 0xff) << 2 | (arr[off+1] & 0xc0) >> 6;
        var b = (arr[off+1] & 0x3f) << 4 | (arr[off+2] & 0xf0) >> 4;
        var c = (arr[off+2] & 0x0f) << 6 | (arr[off+3] & 0xfc) >> 2;
        var d = (arr[off+3] & 0x03) << 8 | (arr[off+4] & 0xff) >> 0;
        
        return [a, b, c, d];
    }
    

    (I’ve assumed most significant bit first order)

    function writeInt10(arr, off, a, b, c, d) {
        arr[off+0] = (a >> 2) & 0xff;
        arr[off+1] = (a << 6) & 0xc0 | (b >> 4) & 0x3f;
        arr[off+2] = (b << 4) & 0xf0 | (c >> 6) & 0x0f;
        arr[off+3] = (c << 2) & 0xfc | (d >> 8) & 0x03;
        arr[off+4] = (d << 0) & 0xff;
    }
    function readInt10(arr, off) {
        var a = (arr[off+0] & 0xff) << 2 | (arr[off+1] & 0xc0) >> 6;
        var b = (arr[off+1] & 0x3f) << 4 | (arr[off+2] & 0xf0) >> 4;
        var c = (arr[off+2] & 0x0f) << 6 | (arr[off+3] & 0xfc) >> 2;
        var d = (arr[off+3] & 0x03) << 8 | (arr[off+4] & 0xff) >> 0;
        return [a, b, c, d];
    }
    const buf = new Uint8Array(5);
    writeInt10(buf, 0, 1023, 100, 512, 768);
    console.log(buf);
    console.log(readInt10(buf, 0));
    Login or Signup to reply.
  2. In order to accomplish the task it seems to be a lot simpler to collect all "excess bits" in a single element, although this makes another storage sequence:

    function writeInt10(arr, off, a, b, c, d)
    {
        arr[off+0] = a & 0xff
        arr[off+1] = b & 0xff
        arr[off+2] = c & 0xff
        arr[off+3] = d & 0xff
        arr[off+4] = (a & 0x300) >> 8 | (b & 0x300) >> 6 | (c & 0x300) >> 4 | (d & 0x300) >> 2
    }
    
    function readInt10(arr, off) {
        const n = arr[off+4] // for convenience
        const a = arr[off+0] | (n & 0x03) << 8
        const b = arr[off+1] | (n & 0x0c) << 6
        const c = arr[off+2] | (n & 0x30) << 4
        const d = arr[off+3] | (n & 0xc0) << 2
    
        return [a, b, c, d]
    }
    
    var buf = new Uint8Array(5)
    var write = writeInt10(buf, 0, 1023, 100, 512, 768)
    var read = readInt10(buf, 0)
    console.log(read)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search