3.20. PACKING 12-BIT VALUES INTO ARRAY
3.20.3 The algorithm.
So the algorithm can be as follows: if the element’s index is even, put it at left side, if the index is odd,
place it at right side. The middle byte: if the element’s index is even, place part of it in high 4 bits, if it’s
odd, place its part in low 4 bits. But first, find the right triplet, this is easy: index 2. Finding the address of
right byte in array of bytes is also easy: index 2 ⋅ 3 orindex⋅^32 or justindex⋅ 1 : 5.
Pulling values from array: if index is even, get leftmost and middle bytes and combine its parts. If index is
odd, get middle and rightmost bytes and combine them. Do not forget to isolate unneeded bits in middle
byte.
Pushing values is almost the same, but be careful not to overwrite someother’sbits in the middle byte,
correcting onlyyours.
3.20.4 The C/C++ code
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#define ARRAY_SIZE (0x1000/2*3)
uint8_t array[ARRAY_SIZE]; // big enough array of triplets
unsigned int get_from_array (unsigned int idx)
{
// find right triple in array:
int triple=(idx>>1);
int array_idx=triple*3;
//assert (array_idx<ARRAY_SIZE);
if (idx&1)
{
// this is odd element
// compose value using middle and rightmost bytes:
return ((array[array_idx+1]&0xF) << 8)|array[array_idx+2];
}
else
{
// this is even element
// compose value using rightmost and middle bytes:
return array[array_idx]<<4 | ((array[array_idx+1]>>4)&0xF);
};
};
void put_to_array (unsigned int idx, unsigned int val)
{
//assert (val<=0xFFF);
// find right triple in array:
int triple=(idx>>1);
int array_idx=triple*3;
//assert (array_idx<ARRAY_SIZE);
if (idx&1)
{
// this is odd element
// put value into middle and rightmost bytes:
// decompose value to be stored:
uint8_t val_lowest_byte=val&0xFF; // isolate lowest 8 bits
uint8_t val_highest_nibble=val>>8; // no need to apply &0xF, we already know ⤦
Çthe val<=0xFFF
// clear low 4 bits in the middle byte:
array[array_idx+1]=array[array_idx+1]&0xF0;