Bit flags aren’t probably something that you think about in traditional/modern software development. You might if you are in the IoT space, but if you have the pleasure of a ton of RAM, you probably aren’t super concerned with saving space. However, recently I’ve been thinking a lot about network communication and how to minimize the amount of information travelling across a network, and bit flags are a great way to save space.
Flag Values
A byte is made up of 8 bits. A bit can exist in two states, either off (0), or on (1). Thus a single bit is perfect for representing a boolean (true/false) value.
A byte:
1 1 1 1 1 1 1 1
As you can see, you could therefore represent 8 different boolean values inside of a single byte by assigning each of them to a specific bit inside of the byte.
In order to address each bit, you just need to remember your powers of 2:
By adding up all of these values: 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128, we get 255 or the maximum value for a single byte.
We can therefore turn any of these bits on independently and get a number that represents those flags being turned on.
For example, if we want the 1st and 3rd flags turned on (2^0 and 2^2), we get 1 + 4 = 5.
Setting Flags
You can set the flags by using a bitwise OR operation. This operation will turn bits to true if they exist in either of the provided bytes:
96 | 5 = 101
0110 0000 |
0000 0101 =
0110 0101
You can keep the original value of the flag by using the |= operator, which works similar to the ++ and += operator.
<script src=”https://gist.github.com/Flayed/1fab5d2705ab8de0f45cc61ba478e0bb.js”></script>
Checking Flags
To check whether a byte contains a flag, you just need to use a bitwise AND operation. This operation will return only the bits that exist in both of the provided bytes:
96 & 5 = 0 96 & 32 = 32
0010 0000 & 0110 0000 &
0000 0101 = 0010 0000 =
0000 0000 0010 0000
So, in order to check for a flag, you just need to see if the value & flag == flag
Enums
So knowing the value of the flags is still important, but it would be pretty irresponsible to hardcode those numbers all over the place without understanding what they are. Luckily, we can use Enums to define the flags, making it easier to use.
When you’re dealing with an Enum, you can treat all of the values as an Enum and blissfully forget about the underlying values.
The [Flags] attribute
Above I used the [Flags] attribute, but I still had to define each value to be a power of 2 in order to make them operate as flags. The [Flags] attribute modifies the enum’s ToString() property to list out all of the values:
There’s also some other things like the Parse method that can parse those strings back into a [Flags]enum.
Unit Testing bit fields – Darchuk.NET
[…] Last week I wrote about bit fields and how they can be used to easily track boolean values. Unit testing is pretty important to me, because I make mistakes a lot. By writing tests, I can have a little bit of confidence in the code that I wrote. […]