Eric’s Arduous BitField Challenge.
Come one, come all. Gentlemen kindly hold on to your hats. Ladies are cautioned that what follows has already caused some able-bodied women to run screaming for the safety of their homes. Children strictly not permitted.
Introduction.
Anyone who has ever had to keep track of any more than a couple flags denoting the state or intended state of one element or another, has had, as Jimmy Carter would say, lust in their heart for the Simple-As-A-Singleton construct or, dare I say, Design Pattern known to the world as a BitField, whether they knew what to call it or not.
Unnecessary Babbling.
By the way, don't worry if you didn't know what to call it—Jimmy Carter didn't know much either. I know this because I've learned, over the last six years, that anyone who pronounces the word "nuclear" as "new-cue-lar" is an idiot, and Jimmy Carter, whose most noteworthy achievement was as the commander of a Cold War nuclear submarine, was the first person I ever heard mispronounce the word.
So if Jimmy Carter is as smart as people like to say he is, and he can't pronounce a word in his job title correctly, anyone who doesn't know what a BitField is, certainly has nothing to fear.
Back On Point: Introducing the BitField.
A BitField is merely the combination of a bunch, usually 32 but can really be any number, of individual flags into a single structure (Class) that provides mechanisms (Methods, or Class Functions) to alter the state of each flag individually, or all the flags as a group.
The most basic BitField Class would define a setFlag and an unSetFlag method, as well as a getFlag method. Each takes a single argument which represents which of the many flags within the BitField should be written to, or returned. The "interface" of the class, then, looks like:
public class Bitfield {
// constructor
public function BitField();
// getter
public function getFlag():Boolean;
// setter
public function setFlag(theIndex:int):void;
// unsetter
public function unSetFlag(theIndex:int):void;
}
The Bit Field, and it's data type.
The actual collection of flags, or bits, is called the bit field. We could certainly call the class "Flags" or something, and call the bit field, "bitField", but for semanticisms sake (and the context of this post), I'm calling the class "BitField", and the bit field, "bits".
private var bits:uint;
Why an unsigned integer? Well, that's the data type with the bit structure, typically (or, rather, when employed by other languages), that provides the greatest number of bits to the number, and is free of that pesky bit that indicates the sign of the value, or whether it is positive or negative. Hopefully the unsigned int works as well in the Flash Player as I'm expecting. If not, we can try a signed integer, or a Number.
Each of the bits within the unsigned integer, will be used as an individual flag. All we have to do is provide access to each bit.
First, though, what exactly do those bits look like?
Well golly, I'm glad you asked. The bits are purple with brown spots and go around with little green hats that squeek when they get wet. Picture the love-child of Barney the Dinosaur and one of the mogwais from Gremlins, and you're close enough to continue.
So, if we care about eight of the thirty-two bits that comprise an unsigned integer, when that "bit field" is empty, it would appear like:
0x00000000
If we set the first and fifth flag, or bit, we wind up with:
0x01000100
If we then set the seventh bit, we get:
0x01000101
Makes sense, yes? But how do we manipulate the flags on the unsigned integer level, you ask. We use Bitwise Operators.
Bitwise Operations In a Nutshell
If you get confused when you see the strict equality operator (===), you may want to just skip ahead because that is downright logical and tame compared to what we're going to deal with.
There are a bunch of bitwise operators to choose from in ActionScript, including bitwise AND (&) and bitwise OR (|). We use these just like any other operator—smack dab in between the two numbers we want to operate upon.
To set an individual bit, we refer to that bit by it's index within the BitField. Or, rather, we can refer to it by anything we want, as long as we use it correctly.
By the way, you can find the most minimal description humanly possible for each bitwise operator in the AS3 documentation.
To see how these operator work, however, Wikipedia does a great job discussing a BitField, and provides a simple example suitable for appropriating for our class.
public class BitField {
private var bits:uint;
// constructor
public function BitField() {
bits = 0;
}
// getter
public function getFlag(theFlag:int):Boolean {
return1 != 0);
}
// setter
public function setFlag(theFlag:int):void {
bits |= theFlag;
}
// unsetter
public function unSetFlag(theFlag:int):void {
bits &= ~(bits & (1 << theFlag));
}
}
So we try it out with:
var myBitField:BitField = new BitField();
myBitField.setFlag(1);
myBitField.setFlag(2);
myBitField. setFlag(12);
And when we run it and tell it to spit out a string containing a "1" for each "set flag", and a "0" for each "un-set flag", we get:
11110000000000000000000000000000
Hmmm. That doesn't look right. For one thing, I only set three flags, not 4, so there's a problem somewhere early on. To find out where, I add another test to see what the data looks like when it is first set to zero:
00000000000000000000000000000000
So we started out ok. What else could be the problem? Should we try a different data tye, say, a signed integer? OK, lets.
SCCCCRREEEEEEEEEEECH! BAMN!
This time, we get exactly the same thing. Exactly. Let's try making them a Number.
No dice. Identical results. And so the post goes screetching to a halt.
What's the deal? This code would work in, say, C++ compiled with a GCC compiler, with only a few, minor changes.
HEEEEEELLLLLP!
- bits & (1 << theIndex [↩]
about this entry
you’re currently skimming and ignoring “Eric’s Arduous BitField Challenge.,”
- published:
- 07.11.07 / 7pm
- category:
- actionscript, flex
nobody cares (yet?)
click to care. click to comment. | comments rss [?] | trackback uri [?]