« Civilization 5 addiction Rebirth »

Bit flags

2010
14
September

As hardware has gotten cheaper and with the advance of high level programming languages developers rarely have to consider cpu, memory limitations, or efficiency when they write their code. The obvious exception being developers working on drivers, operating systems or other low level operations.

The pros of this are obvious to most developers but one con that is often overlooked is that certain idioms and tricks of the trade have become something of a lost art.

Using bit flags, once a rudimentary technique, is often overlooked by "younger" developers. Since memory limitations are seldom a factor in development today this technique has been abandoned in favor of just adding another variable or database field.

Since I'm writing this post during my coffee break, explaining the concept of bit flags and bitwise operations is out of the scope of this blog post. Instead I thought I'd show some common implementation/usage mistakes that I've run across. If you'd like to learn more here's some links to get you started:
PHP bitwise operators,
Bitwise operations and
Bit fields.

PHP being my web language of choice, thats what I'll use for the examples.
These are the flags we'll use:


define('FLAG_0', 1);
define('FLAG_1', 2);
define('FLAG_2', 4);
define('FLAG_3', 8);

Case 1

The first mistake I'll show is the one I've seen the most. It's an implementation of a setFlag function. The problem is that the function fails when setting multiple flags at once.


function setFlag($flag)
{
        global $flags;

        if (($flags & $flag))
        {
                return;
        }

        $flags |= $flag;
}

setFlag(FLAG_2); // this works
setFlag(FLAG_1 | FLAG_2); // this doesn't

The problem lies in the conditional. If we alter it slightly it will work as intended.
Replace:

if (($flags & $flag))

with:

if (($flags & $flag) == $flag)

case 2

When it comes to removing flags I've sometimes seen people using the operator ^=. Using that operator might seem to work at first because if the flag is set it will be unset. However if the flag is not set it will be set. In other words the ^= operator works as a toggle.


function removeFlag($flag)
{
        global $flags;

        $flags ^= $flag;
}

setFlag(FLAG_1);
removeFlag(FLAG_3);
// $flags is now 10 when it should be 2

The operator to use is &= in conjunction with ~.


function removeFlag2($flag)
{
        global $flags;

        $flags &= ~$flag;
}

setFlag(FLAG_1);
removeFlag(FLAG_3); // $flags is still 2

I made a simple PHP script bitflags.php with more test cases for you to toy with. Thats all for now.

When running a high traffic site memory management and speed of execution becomes a factor. At Flattr.com we make extensive use of bit flags to make the memory footprint as small as possible.


0 Responses to Bit flags

Feed for this Entry

0 Comments

    There are currently no comments.

About You

Email address is not published

Add to the Discussion