RSS LinkedIn Twitter

Using Bit-wise Math to Simplify Logic

August 19th, 2009 Categories: Actionscript, Design Patterns, Flex 3, Flex 4, Scalability

Strictly speaking, bit strings are not nearly as easy to understand as named boolean variables; but there are situations when they can simplify or eliminate the need for long boolean expressions.

Consider my recent post about the ShortcutManager. There are three control keys that may or may not be pressed at any given time. This amounts to 8 possible key combinations (7 if you ignore when none of them are pressed). Here’s what this would look like if you used a boolean expression to check for each of the possible combinations:

[as3]
var ctrl : Boolean = event.ctrlKey;
var alt : Boolean = event.altKey;
var shift : Boolean = event.shiftKey;

if (!shift && !alt && ctrl) {
// CTRL
}
else if (!shift && alt && !ctrl) {
// ALT
}
else if (!shift && alt && ctrl) {
// CTRL-ALT
}
else if (shift && !alt && !ctrl) {
// SHIFT
}
else if (shift && !alt && ctrl) {
// CTRL-SHIFT
}
else if (shift && alt && !ctrl) {
// SHIFT-ALT
}
else if (shift && alt && ctrl) {
// CTRL-SHIFT-ALT
}
[/as3]

That might not seem too bad, and it isn’t that hard to understand what’s going on (even without the comments). But what happens when you’ve got 4 variables (16 possibilities)? The number of combinations increase exponentially. Even if the combinations you are actually interested in are sparse, who wants to type out 10 lines each with 32 boolean variables?

With a simple method to construct my “bit string”, we can greatly simplify this. ActionScript doesn’t have a binary number type, so you’ll have to use integers. If you can count by powers of two you won’t have any trouble. Here’s a method that constructs my “bit string” integer based on selected control keys:

[as3]
private static function getFlags(event : KeyboardEvent) : uint {
var flags : uint = 0;
flags += (event.ctrlKey) ? 1 : 0;
flags += (event.altKey) ? 2 : 0;
flags += (event.shiftKey) ? 4 : 0;

return flags;
}
[/as3]

Having this integer allows me to simplify the logic as follows (which isn’t harder to understand at all, if you use comments):

[as3]
switch ( getFlags(event) ) {
case 1: // CTRL
break;
case 2: // ALT
break;
case 3: // CTRL-ALT
break;
case 4: // SHIFT
break;
case 5: // CTRL-SHIFT
break;
case 6: // SHIFT-ALT
break;
case 7: // CTRL-SHIFT-ALT
break;
}
[/as3]

This is powerful, but it’s just scratching the surface. I haven’t even discussed the bitwise operators &, | and ^. Or the bitwise shift operators >> and <<. These come in handy when you store a series of options as a bit string and need to test whether a certain option is on or off.

For example, if we needed to test if value returned by getFlags() had the SHIFT bit set, we could use the following boolean expression to test it. Remember SHIFT = 4:

[as3]if (getFlags(event) & 4 == 4)[/as3]

Of course this doesn’t help us out much now in the ShortcutManager, but assume I was to add 3 possible contexts that these shortcuts might be used in (different screens, for example). They would hold the 8, 16, and 32 bit places. I could use bitwise math to split them if I only needed to manipulate one them at a time (a stretch, I know).

[as3]
var screenOnly: uint = flags & 56;
var keysOnly: uint = flags & 7;
[/as3]

They have a variety of uses and are there when you need them. There’s an excellent explanation of various bitwise operations and their uses here.

Tags: , ,
No comments yet.

Leave a Comment

*