X
    Categories: .NET

Bitwise operators makes us storagewise

Not having a computer science or mathematical background, I had a vague idea of bitwise operators, but never needed them for anything practical. Until now that is. I’m building a form with a CheckedListBox. This listbox contains items that can be checked or unchecked. The items themselves are added from an enumeration, say TestOptions. The user can check multiple items but I only have one variable to store the selection. Ok, I could have more, but figured it to be a waste to check the state of each item and store that in a seperate variable. There should be something more efficient to do this. So here goes:

First here’s the enum type:

public enum TestOptions {

            OptionA = 1,

            OptionB = 2,

            OptionC = 4,

            OptionD = 8

        }

It’s important to give each enumvalue an explicit integer value. These values need to be incremented by a multiple of 2 (so: 1, 2, 4, 8, 16, 32, etc). This enables us to make unique combinations of a set of enum values. I.e. the setvalue of 5 can only be attributed to a selection of 1 and 4. The value of 7 can only come from a selection of 1, 2 and 4.

To fill the listbox with items and set their checked state, this method is called:

        private void SetCheckedListBoxItems(int value) {

            foreach (int enumValue in Enum.GetValues(typeof(TestOptions)) ) {

                CheckState state = CheckState.Unchecked;

                if((value & enumValue) == enumValue) {

                    value ^= enumValue;

                    state = CheckState.Checked;                     

                }               

                checkedListBox1.Items.Add(Enum.GetName(typeof(TestOptions), enumValue), state);               

            }

        }

The value that is passed to this method is the sum of the items from the enum that are checked. For example: SetCheckedListBoxItems(9). The method will loop through each enum value. The default state is unchecked. Then we check to see if the submitted value is contained in a bitfield. For integral types like we have here, & computes the bitwise AND of its operands. What this means is that it returns the bits that are common between the two operands. Wait a minute, we went from integer to bit, what, how, when? Well, an integer is composed of 32 bits in the .NET Framework, which means that 32 zeros and ones represent the actual integer value. To clarify, take the value of 9 which can be represented as: 1001. For brevity, let’s omit the 28 zeros preceding 1001.

Suppose this value of 9 is submitted to the method shown above. Once in the loop it checks against the value of 2, being one of the enum values. The number 2 in bits is: 0010. The outcome of (1001 & 0010) = 0000, effectively zero, so there’s no match and we don’t check the item. Further in the loop we get the enumvalue of 8, representable as: 1000. We check which bits are the same (1001 & 1000) and the result is … 1000, which is 8 in integer terms.

So we know that the item representing the enumvalue of 8 needs to be checked. We then combine the bits such that if exactly one is 1, the result is 1, else the result is 0. For this, we use the ^= operator also known as the exclusive-OR assignment operator. Performing the operation 1001 ^= 1000 sets the value to 0001, which is 1 as an integer. So when the loop encounters the enumvalue of 1, the evaluation will give the proper result, and make sure we also check the listitem for the enumvalue representing 1. You would assume we encounter the value of 1 before we see 8 in our loop through the enumtype and while this is true, it doesn’t matter. Try this for yourself.

After a new selection is made, we want to save the new value. This is very simple.

        private void SaveSelection() {

            int newvalue = 0;

            foreach (string item in checkedListBox1.CheckedItems) {

                newvalue += (int)Enum.Parse(typeof(TestOptions), item);

            }

            // show the value, or persist somewhere, whatever…

            MessageBox.Show(“value: ” + newvalue);

        }

The concept allows for very efficient storage of selections. Looking back on previous apps, I could have used this more in my applications. How about you?

Related Post
Leave a Comment