3.20. PACKING 12-BIT VALUES INTO ARRAY
512th element (0x200) is beginning. I added square brackets in my text editor to show triplets explicitly.
Take a notice at the middle bytes, where the last element is ended and the next is started. In other words,
each middle byte has lowest 4 bits of even element and highest 4 bits of odd element.
(gdb) x/300xb array+512/2*3
0x601380 <array+768>: [ 0x20 0x02 0x01 ][ 0x20 0x22 0x03 ][ 0x20 0x42
0x601388 <array+776>: 0x05 ][ 0x20 0x62 0x07 ][ 0x20 0x82 0x09 ][ 0x20
0x601390 <array+784>: 0xa2 0x0b ][ 0x20 0xc2 0x0d ][ 0x20 0xe2 0x0f ]
0x601398 <array+792>: [ 0x21 0x02 0x11 ][ 0x21 0x22 0x13 ][ 0x21 0x42
0x6013a0 <array+800>: 0x15 ][ 0x21 0x62 0x17 ][ 0x21 0x82 0x19 ][ 0x21
0x6013a8 <array+808>: 0xa2 0x1b ][ 0x21 0xc2 0x1d ][ 0x21 0xe2 0x1f ]
0x6013b0 <array+816>: [ 0x22 0x02 0x21 ][ 0x22 0x22 0x23 ][ 0x22 0x42
0x6013b8 <array+824>: 0x25 ][ 0x22 0x62 0x27 ][ 0x22 0x82 0x29 ][ 0x22
0x6013c0 <array+832>: 0xa2 0x2b ][ 0x22 0xc2 0x2d ][ 0x22 0xe2 0x2f ]
0x6013c8 <array+840>: [ 0x23 0x02 0x31 ][ 0x23 0x22 0x33 ][ 0x23 0x42
0x6013d0 <array+848>: 0x35 ][ 0x23 0x62 0x37 ][ 0x23 0x82 0x39 ][ 0x23
0x6013d8 <array+856>: 0xa2 0x3b ][ 0x23 0xc2 0x3d ][ 0x23 0xe2 0x3f ]
0x6013e0 <array+864>: [ 0x24 0x02 0x41 ][ 0x24 0x22 0x43 ][ 0x24 0x42
0x6013e8 <array+872>: 0x45 ][ 0x24 0x62 0x47 ][ 0x24 0x82 0x49 ][ 0x24
0x6013f0 <array+880>: 0xa2 0x4b ][ 0x24 0xc2 0x4d ][ 0x24 0xe2 0x4f ]
0x6013f8 <array+888>: [ 0x25 0x02 0x51 ][ 0x25 0x22 0x53 ][ 0x25 0x42
0x601400 <array+896>: 0x55 ][ 0x25 0x62 0x57 ][ 0x25 0x82 0x59 ][ 0x25
0x601408 <array+904>: 0xa2 0x5b ][ 0x25 0xc2 0x5d ][ 0x25 0xe2 0x5f ]
0x601410 <array+912>: [ 0x26 0x02 0x61 ][ 0x26 0x22 0x63 ][ 0x26 0x42
0x601418 <array+920>: 0x65 ][ 0x26 0x62 0x67 ][ 0x26 0x82 0x69 ][ 0x26
0x601420 <array+928>: 0xa2 0x6b ][ 0x26 0xc2 0x6d ][ 0x26 0xe2 0x6f ]
0x601428 <array+936>: [ 0x27 0x02 0x71 ][ 0x27 0x22 0x73 ][ 0x27 0x42
0x601430 <array+944>: 0x75 ][ 0x27 0x62 0x77 ][ 0x27 0x82 0x79 ][ 0x27
0x601438 <array+952>: 0xa2 0x7b ][ 0x27 0xc2 0x7d ][ 0x27 0xe2 0x7f ]
0x601440 <array+960>: [ 0x28 0x02 0x81 ][ 0x28 0x22 0x83 ][ 0x28 0x42
0x601448 <array+968>: 0x85 ][ 0x28 0x62 0x87 ][ 0x28 0x82 0x89 ][ 0x28
0x601450 <array+976>: 0xa2 0x8b ][ 0x28 0xc2 0x8d ][ 0x28 0xe2 0x8f ]
0x601458 <array+984>: [ 0x29 0x02 0x91 ][ 0x29 0x22 0x93 ][ 0x29 0x42
0x601460 <array+992>: 0x95 ][ 0x29 0x62 0x97 ][ 0x29 0x82 0x99 ][ 0x29
0x601468 <array+1000>: 0xa2 0x9b ][ 0x29 0xc2 0x9d ][ 0x29 0xe2 0x9f ]
0x601470 <array+1008>:[ 0x2a 0x02 0xa1 ][ 0x2a 0x22 0xa3 ][ 0x2a 0x42
0x601478 <array+1016>: 0xa5 ][ 0x2a 0x62 0xa7 ][ 0x2a 0x82 0xa9 ][ 0x2a
0x601480 <array+1024>: 0xa2 0xab ][ 0x2a 0xc2 0xad ][ 0x2a 0xe2 0xaf ]
0x601488 <array+1032>:[ 0x2b 0x02 0xb1 ][ 0x2b 0x22 0xb3 ][ 0x2b 0x42
0x601490 <array+1040>: 0xb5 ][ 0x2b 0x62 0xb7 ][ 0x2b 0x82 0xb9 ][ 0x2b
0x601498 <array+1048>: 0xa2 0xbb ][ 0x2b 0xc2 0xbd ][ 0x2b 0xe2 0xbf ]
0x6014a0 <array+1056>:[ 0x2c 0x02 0xc1 ][ 0x2c 0x22 0xc3 ][ 0x2c 0x42
0x6014a8 <array+1064>: 0xc5 ][ 0x2c 0x62 0xc7 ]
3.20.5 How it works
Let array be a global buffer to make simpler access to it.
Getter
Let’s first start at the function getting values from the array, because it’s simpler.
The method of finding triplet’s number is just division input index by 2, but we can do it just by shifting
right by 1 bit. This is a very common way of dividing/multiplication by numbers in form of 2 n.
I can demonstrate how it works. Let’s say, you want to divide 123 by 10. Just drop last digit (3, which is
remainder of division) and 12 is left. Division by 2 is just dropping least significant bit. Dropping can be
done by shifting right.
Now the functions must decide if the input index even (so 12-bit value is placed at the left) or odd (at the
right). Simplest way to do so is to isolate lowest bit (x&1). If it’s zero, our value is even, otherwise it’s
odd.
This fact can be illustrated easily, take a look at the lowest bit:
decimal binary even/odd