You are on page 1of 5

1.

Bitflags are a method of storing multiple values, which are not mutually exclusive, in one variable. You've probably seen them before. Each flag is a bit position which can be set on or off. You then have a bunch of bitmasks #defined for each bit position so you can easily manipulate it:
#define #define #define #define #define #define LOG_ERRORS LOG_WARNINGS LOG_NOTICES LOG_INCOMING LOG_OUTGOING LOG_LOOPBACK 1 2 4 8 16 32 // // // // // // 2^0, bit 0 2^1, bit 1 2^2, bit 2 2^3, bit 3 2^4, bit 4 and so on...

// Only 6 flags/bits used, so a char is fine unsigned char flags; // initialising the flags // note that assignming a value will clobber any other flags, so you // should generally only use the = operator when initialising vars. flags = LOG_ERRORS; // sets to 1 i.e. bit 0 //initialising to multiple values with OR (|) flags = LOG_ERRORS | LOG_WARNINGS | LOG_INCOMING; // sets to 1 + 2 + 8 i.e. bits 0, 1 and 3 // setting one flag on, leaving the rest untouched // OR bitmask with the current value flags |= LOG_INCOMING; // testing for a flag // AND with the bitmask before testing with == if ((flags & LOG_WARNINGS) == LOG_WARNINGS) // or check != 0 after & if ((flags & LOG_WARNINGS) != 0) // testing for multiple flags // as above, OR the bitmasks if ((flags & (LOG_INCOMING | LOG_OUTGOING)) == (LOG_INCOMING | LOG_OUTGOING)) ... // removing a flag, leaving the rest untouched // AND with the inverse (NOT) of the bitmask flags &= ~LOG_OUTGOING; // toggling a flag, leaving the rest untouched flags ^= LOG_LOOPBACK;

WARNING: DO NOT use the equality operator (i.e. bitflags == bitmask) for testing if a flag is set - that expression will only be true if that flag is set and all others are unset. To test for a single flag you need to use & and == :
if (flags == LOG_WARNINGS) //DON'T DO THIS ... if ((flags & LOG_WARNINGS) == LOG_WARNINGS) // The right way ... if ((flags & (LOG_INCOMING | LOG_OUTGOING)) // Test for multiple flags set == (LOG_INCOMING | LOG_OUTGOING))

2.
I'm going to be more explicit here because I think bitwise masks are a great tool that should be in any devs belt. I'm going to try to expand on the answers above. First, an example of using an integer to maintain state flags (common usage):
// These are my masks private static final int MASK_DID_HOMEWORK private static final int MASK_ATE_DINNER private static final int MASK_SLEPT_WELL // This is my current state private int m_nCurState; = 0x0001; = 0x0002; = 0x0004;

To set my state, I use the bitwise OR operator:


// Set state for'ate dinner' and 'slept well' to 'on' m_nCurState = m_nCurState | (MASK_ATE_DINNER | MASK_SLEPT_WELL);

Notice how I 'or' my current state in with the states that I want to turn 'on'. Who knows what my current state is and I don't want to blow it away. To unset my state, I use the bitwise AND operator with the complement operator:
// Turn off the 'ate dinner' flag m_nCurState = (m_nCurState & ~MASK_ATE_DINNER);

To check my current state, I use the AND operator:


// Check if I did my homework if (0 != (m_nCurState & MASK_DID_HOMEWORK)) { // yep } else { // nope... }

Why do I think this is interesting? Say I'm designing an interface that sets my state. I could write a method that accepts three booleans:
void setState( boolean bDidHomework, boolean bAteDinner, boolean bSleptWell);

Or, I could use a single number to represent all three states and pass a single value:
void setState( int nStateBits);

If you choose the second pattern you'll be very happy when decide to add another state - you won't have to break existing impls of your interface. My two cents. Thanks.

2.
Requirement: I have a grid with several columns and I want to persist their state of visibility into the database. How do I implement this in the most effective way? For this requirement, you need to use bit conservation technique (not a ninjutsu!), which means saving data or group of data that can be represented as series of bits into a single value. In our requirement, we only need to store the columns visibility represented as 1 (on/visible) or 0 (off/hidden) bits. An integer, in most cases, is sufficient because it has 32 bits (Note: On dotNet, a managed integer is consistently 32-bit, across 32/64 bit systems. On other languages like C/C++, native integer type is machine-dependent) To explain the solution is to go straight to the code. So here it goes. Assuming we have a grid where we need 6 columns to save their visibility state. Use constants to represent each columns bit mask to make our code readable enough. const const const const const const int int int int int int COLUMN_A COLUMN_B COLUMN_C COLUMN_D COLUMN_E COLUMN_F = = = = = = 0x1; 0x2; 0x4; 0x8; 0x10; 0x20;

In our example, you may find using a 32-bit integer too much for our requirement since we are only using 6 bits. In this case, 16-bit short type will do. To illustrate, if all columns are visible we should have the first 6 low-order bits set to 1 (0011 1111). private void saveColumnState() { int colInfo = 0; if (colA.IsVisible) colInfo |= COLUMN_A; if (colB.IsVisible) colInfo |= COLUMN_B; /* ... other columns ... */ /* call saving routine here */ } To put together bits, we use the OR bit operator. In the above code, I first declared an integer where all bits are initially set to 0 (off). Then, for each visible column, I turn on the target bit with the columns corresponding constant bit mask. To illustrate, if columns A, B, D & E are hidden, the operations would be: Init: 0000 0000 (all 6 columns hidden/off) OR: 0010 0000 (turn on column F) Result: 0010 0000 OR: 0000 0100 (turn on column C) Result: 0010 0100 (0-0-F-E D-C-B-A) /* colsInfo is a value initialized from the data source. */ private void loadColumnState(int colsInfo) { colA.IsVisible = (colInfo & COLUMN_A) > 0; colA.IsVisible = (colInfo & COLUMN_B) > 0; /*other columns*/ } To load the state values, we obviously start off by first extracting the persisted integer value from the data source. To pull out each column data from the persisted integer, we use the AND operator

against the columns constant bit mask to test if that bit is set, or not equal to zero. To illustrate, assuming we want to test if column E and F should be visible, Init: AND: Result: Init: AND: Result: 0010 0100 0001 0000 (COLUMN_E) 0000 0000 (returns zero, COLUMN_E is not visible). 0010 0100 0010 0000 (COLUMN_F) 0010 0000 (returns COLUMN_F also, or simply, non-zero).

As you can see, we have removed several overheads from different aspects of an application. From the database, if youre using one, youre saving space because rather than defining individual bit columns, you are declaring only one integer column. This will obviously minimize the data handling routines, too. Memory usage is also minimal because we only deal with scalar values of integers and bits which are already native to the processor. Note: Our above example could have been a lot simpler by collecting all columns into a strongly typed collection. /* colInfo is a value initialized from the data source. */ private void loadColumnState(Column[] columns, int colInfo) { for (int b = 1, c = 0; c < columns.Length; c++, b *= 2) { columns[c].IsVisible = (colInfo & b) > 0; } } private void saveColumnState(Column[] columns) { int colInfo = 0; for (int b = 1, c = 0; c < columns.Length; c++, b *= 2) { if (columns[c].IsVisible) colInfo |= b; System.Diagnostics.Debug.WriteLine(b); } /* call saving routine here */ } Disclaimer: Am not a C# guru but I hope this article will help.

You might also like