0

I have a char* string coming in. I need to store it accordingly.

The string can be any of those values { UK, GD, BD, ER, WR, FL}

If I want to keep them as enumerated type, which data type is the best to use. Like for 6 values three bits is enough, but how to store three bits in C?

5
  • value:2 doesn't work? Also, with 6 values, two bits isn't enough. You need 3. Commented Oct 4, 2013 at 18:17
  • 2
    "Two bits is enough"... are you going to do something fundamentally important with the other six bits, or just making life harder for no reason? Commented Oct 4, 2013 at 18:18
  • 1
    How exactly do you propose to store a choice from six options in two bits? Commented Oct 4, 2013 at 18:19
  • Why do you want to optimize the number of bits you use? Are you running on platform with only 4K of memory? Just let the compiler use as many bits as it wants. (most likely 8, 16, or 32 bits) Commented Oct 4, 2013 at 18:25
  • 1
    Unless you are under extremely constrained memory conditions, or need to store several bajillion of these, just use an int. Your code will have better performance if you just allow the compiler to use the platforms natural word size. Commented Oct 4, 2013 at 19:07

3 Answers 3

4

What you want is a Bit Field:

typedef struct {
    unsigned char val : 2; //use 2 bits
    unsigned char : 6; // remaining 6 bits
} valContainer;

...

valContainer x;
x.val = GD;

Do note that there isn't really a way to store less than one byte, as the definition of a byte is the smallest amount of memory the computer can address. This is just a method of having names associated with different bits in a byte.

Also, of course, 2 bits is not enough for 6 values (2 bits hold 4 distinct values). So you really want at least 3 bits (8 distinct values).

Sign up to request clarification or add additional context in comments.

Comments

1

Just store them as an unsigned short. Unless you're storing other things in your struct to fill out a whole word, you're WAY prematurely optimizing. The compiler will have to pad out your data anyway.

2 Comments

unsigned short seems odd; maybe unsigned char or just int?
Yeah anything like that would work fine. I'm not sure why I chose unsigned short, no particular reason I guess.
0

As the answer by Eric Finn suggests, you can use bit fields to store a data element of 3 bits. However, this is only good if you have something else to store in the same byte.

struct {
    unsigned char value: 3;
    unsigned char another: 4;
    unsigned char yet_another: 5;
    // 12 bits declared so far; 4 more "padding" bits are unusable
} whatever;

If you want to store an array of many such small elements, you have to do it in a different way, for example, clumping 10 elements in each 32-bit word.

int n = ...; // number of elements to store
uint32_t *data = calloc(n / 10, sizeof(*data));
for (int i = 0; i < n; i++)
{
    int value = read_string_and_convert_to_int();
    data[i / 10] &= ~(7 << (i % 10 * 3));
    data[i / 10] |= value << (i % 10 * 3);
}

If you want to have only one element (or a few), just use enum or int.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.