Monday, November 03, 2008

Bit Flags: The Simple Way


Time from time we face the need or (for some of us) an opprotunity to mess with the bit fields. As we all know bytes consist of bits. Bit can have two values "0" and "1".

Using this knowledge we can store several flags under single byte. In one byte of information we can efficiently store eight one bit flags (1 byte has 8 bits). If we use int values, which has four bytes - we can store 32 bit flags (4*8=32).

So, lets define 8 bit flags. We should receive following picture.

00000001 - 1-st flag
00000010 - 2-nd flag
00000100 - 3-rd flag
00001000 - 4-th flag
00010000 - 5-th flag
00100000 - 6-th flag
01000000 - 7-th flag
10000000 - 8-th flag

There are two ways how to define these flags in C#. Here is the first way: convert each binary number into hexadecimal representation (decimal can be also used). The result will be like this:
[Flags]
public enum FirstApproach : byte
{
First = 0x01,
Second = 0x02,
Third = 0x04,
Forth = 0x08,
Fifth = 0x10,
Sixth = 0x20,
Seventh = 0x40,
Eighth = 0x80,
}
We obtained rather compact definition. But if someone cannot convert binary (01000000) into hex (0x40) number very fast - she will have to use some special tool like calc.exe :). I consider the above mentioned way little bit tiresome.

Here is the second approach: we define "base" at first.
[Flags]
public enum DefBase : byte
{
First = 0,
Second = 1,
Third = 2,
Forth = 3,
Fifth = 4,
Sixth = 5,
Seventh = 6,
Eigth = 7,
}
Then, using "base" we can define our flags:
[Flags]
public enum SecondApproach : byte
{
First = 1 << (byte)DefBase.First,
Second = 1 << (byte)DefBase.Second,
Third = 1 << (byte)DefBase.Third,
Forth = 1 << (byte)DefBase.Forth,
Fifth = 1 << (byte)DefBase.Fifth,
Sixth = 1 << (byte)DefBase.Sixth,
Seventh = 1 << (byte)DefBase.Seventh,
Eighth = 1 << (byte)DefBase. Eigth,
}
Using 2-nd approach does not involve conversion from binary to hex. Using this method we can reuse DefBase multiple times to create required bit flags. Defining next bit flag is no more pain.

If application will have a lot of bit flags declarations then it is more usefull to use 2-nd approach as it can save time of not using additional tools.