Search code examples
cbit-fields

Separating bits in a bitfield


Lets say I have a bitfield structure:

typedef struct{
   unsigned int a:2;
   unsigned int b:4;
   unsigned int c:4;
}bf1

And lets say I have set the bits like this:

bf1.a=2;
bf1.b=9;
bf1.c=8;

Now, I want to separate the bitfield into two parts of 5 and 5.
If the bits currently look like this 1000100110
I want to separate it into 10001 -> 17 and 00110 -> 6.


Solution

  • It's up the compiler to decide the order of the fields in a bit-field.

    The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined.

    So what you are trying to achieve is not possible using bit fields unless you target a specific compiler and platform. (You would use a union of bit fields if the order was predictable.)

    You will therefore need to perform the bit manipulations manually.

    unsigned bf =
         ( 8 << 8 )
       | ( 9 << 4 )
       | ( 2 << 0 );
    
    unsigned x = ( bf >> 5 ) & 0x1F;  // `& MASK` not needed for most significant field.
    unsigned y = ( bf >> 0 ) & 0x1F;
    

    or

    unsigned bf = 0;
    
    bf = ( bf & ~0x3C0 ) | ( 8 << 8 );
    bf = ( bf & ~0x03C ) | ( 9 << 4 );
    bf = ( bf & ~0x003 ) | ( 2 << 0 );
    
    unsigned x = ( bf >> 5 ) & 0x1F;  // `& MASK` not needed for most significant field.
    unsigned y = ( bf >> 0 ) & 0x1F;
    

    The second version works even if the field isn't previously zero.

    Of course, this code can be cleaned up using defines and functions. See this answer to an earlier question for an example.