TIP: Using Unions for Manipulating Bits

This is simple custom data type that allows you to manipulate bits, bytes, or whatever comes into a 32 bit integer. It uses unions for this purpose because all data types within a union share the same memory. This can be very useful for low level purposes such as setting flags without using masking.

Here is the custom type union comprising one DWORD.

typedef struct _BITS8 
{
      unsigned char bit0 : 1;  
      unsigned char bit1 : 1;  
      unsigned char bit2 : 1;  
      unsigned char bit3 : 1; 
      unsigned char bit4 : 1; 
      unsigned char bit5 : 1; 
      unsigned char bit6 : 1; 
      unsigned char bit7 : 1; 
}BITS8;  

typedef struct _QUATERS
{
      unsigned char quater0 : 4; 
      unsigned char quater1 : 4; 
}QUATERS;


typedef	union   _BITSQUATERS
{ 
      BITS8 bits;
      QUATERS quaters;
      unsigned char byte;
}BITSQUATERS;  

typedef union  _BITS32            
{    

      //all 4 bytes - represented as 8 bits and 2 quaters
      BITSQUATERS byte[4];
      short word[2]; //two 16 bit int
      int dword;     //32 bit int

}BITS32;

The structure BITS8 represents single byte as 8 separate bits you can access! If you have a variable of type char and you wish to change some of the bits within it, then all you have to do is take its address, cast it to BITS8 * and then you can change whichever bit you like.

      char c = 0;
      BITS8 *pBits8 = (BITS8  *)&c;
      pBits8->bit4 = 1;//set bit4 of variable c

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
Fig.1
The way struct BITS8 represents one byte in memory

If you would want to change the the high an low quater of varialble c, then cast its address to QUATERS * just like this:

      char c=0;
      QUATERS *pQuaters=(QUATERS *)&c;
      pQuaters->quater0 = 0xC; //set the low quater of c
      pQuaters->quater1 = 0xD; //set the high quater of c

quater1 quater0
Fig.2
The way struct QUATERS represents one byte in memory

If you want to set bits, quaters or the whole byte, then use the BITSQUTERS * pointer this way:

      char c=0;
      BITSQUATERS *pBitsQuaters =(BITSQUATERS *)&c;
      pBitsQuaters->byte = 0xFF;           //set the whole byte
      pBitsQuaters->quaters.quater0 = 0xC; //set the low quater of c
      pBitsQuaters->quaters.quater1 = 0xD; //set the high quater of c
      pBitsQuaters->bits.bit7 = 0;         //set bit7

BYTE
quater1 quater0
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
Fig.3
The way union BITSQUATERS represents one byte in memory

Here is how to set up dword, low and high word, separate bytes and bits as well — using a BITS32 * pointer:

      int i = 0; 
      BITS32 * pbits32 = (BITS32 *) &i; 
      pbits32->dword = 0x33221100;     	//set all 32 bits 
      pbits32->word[0] = 0xcc11;          //set low int16 of dword
      pbits32->byte[0].byte = 0xff;   //set first byte 
      pbits32->byte[0].quaters.quater0 = 0xF;//set first byte low quarter
      pbits32->byte[3].bits.bit7 = 1; //set third byte bit7 

DWORD
WORD1 WORD0
byte3 byte2 byte1 byte0
quater1 quater0 quater1 quater0 quater1 quater0 quater1 quater0
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
Fig.4
The way union BITS32 represents one double word in memory

Hope that will come in handy! Enjoy



Downloads

Comments

  • Endian considerations

    Posted by foxmuldr on 02/24/2010 01:02am

    Depending on the machine, big-endian or little-endian compatibility issues could also arise. As long as you're dealing with a single machine it should be okay, but if you're designing code to interact with other systems it will likely break.

    Reply
  • Just be aware of this

    Posted by S_M_A on 07/02/2009 03:34pm

    The packing order for bitfields is not standardized i.e. this type of code is not very portable. To further complicate things, using unsigned chars in bitfields isn't according to the standard either so changing compiler might also make the code break.

    Reply
  • Some code examples would be nice to have

    Posted by CBasicNet on 06/09/2009 09:51pm

    Hi bat_lubo2001,
    
    Thanks for this useful tip. Some code examples on how to access the members of this complex union would be very nice to have for beginners.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: March 19, 2015 @ 1:00 p.m. ET / 10:00 a.m. PT The 2015 Enterprise Mobile Application Survey asked 250 mobility professionals what their biggest mobile challenges are, how many employees they are equipping with mobile apps, and their methods for driving value with mobility. Join Dan Woods, Editor and CTO of CITO Research, and Alan Murray, SVP of Products at Apperian, as they break down the results of this survey and discuss how enterprises are using mobile application management and private …

  • On-demand Event Event Date: February 12, 2015 The evolution of systems engineering with the SysML modeling language has resulted in improved requirements specification, better architectural definition, and better hand-off to downstream engineering. Agile methods have proven successful in the software domain, but how can these methods be applied to systems engineering? Check out this webcast and join Bruce Powel Douglass, author of Real-Time Agility, as he discusses how agile methods have had a tremendous …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date