TAGS :Viewed: 14 - Published at: a few seconds ago

[ Using bit packing to mimic functionality of 3d array in c ]

I have a 3d boolean array of the following dimensions: bool myArray[streamCount][dayCount][minuteCount]; where dayCount = 500, streamCount = 11,000 and minuteCount = 400;

I am trying to dramatically shrink the memory requirements of this array by using bit packing. I need to retain the ability to randomly access any of the values, in the same way I do now with the 3d array.

Below is the (brain-dead) scheme I devised. It has the problem that to find the value, I need to set up 8 if statements. Is there an easier way to do this?

#define STREAM_COUNT 11000
#define DAY_COUNT 500

typedef struct s_minuteStorage 
 {
 unsigned char a: 1;
 unsigned char b: 1;
 unsigned char c : 1;
 unsigned char d : 1;
 unsigned char e: 1;
 unsigned char f: 1;
 unsigned char g : 1;
 unsigned char h : 1;

 } minuteStorage;


typedef struct s_itemStorage
{
    minuteStorage Minutes[STREAM_COUNT][50];
} itemStorage;

itemStorage *Items;

void allocStorage(void)
{
    Items = (itemStorage *) ecalloc(DAY_COUNT, 1);
}


int getMinuteValue(int minuteIndex, int dayIndex, int streamIndex)
{
    int minuteArrayIndex = minuteIndex / 8;
    int remainder = minuteIndex % 8;
    int value;

    if (remainder == 0)
        value = Items[dayIndex].Minutes[streamIndex][minuteArrayIndex].a;
    if (remainder == 1)
        value = Items[dayIndex].Minutes[streamIndex][minuteArrayIndex].b;
    if (remainder == 2)
        value = Items[dayIndex].Minutes[streamIndex][minuteArrayIndex].c;

    //  etc

    return(value);
}

Answer 1


Instead of using a struct, you can just use an unsigned char and shift by the proper number of bits:

typedef unsigned char minuteStorage;

int getMinuteValue(int minuteIndex, int dayIndex, int streamIndex)
{
    int minuteArrayIndex = minuteIndex / 8;
    int remainder = minuteIndex % 8;
    minuteStorage m = Items[dayIndex].Minutes[streamIndex][minuteArrayIndex];
    return (m >> remainder) & 1;
}