On the path of beeing the As3 world master scripter there is something important to know about number manipulation.
Even if we are normally dealing with the as3 numbers type such uint, int and Number as normal object (java type wrapper like), we can take advance on how the integer number are rappresented and handle by the flash player.
The base concept, as “Bitwise” may suggest, is to use the bit representation of the number.
A number can be represented in an infinite number of ways. The representation we are used to is called decimal, or base 10.
The binary, or base 2, number system is the one that computers use to represent numbers in memory. Since we’re dealing with base 2, there are only two digits available, namely 0 and 1. Each digit is multiplied by successive powers of two to obtain the number’s overall value.
Following some of the useful/interesting implementation of the art of handle bit.
Multiplication and Division by 2 (or multiple of 2)
bitwise left and right shift
// this is the normal way to divide or moltiply y for a multiple of // 2 (0,1,2,4,8...) y *= Math.pow(2,x); y /= Math.pow(2,x);
// this is the bitwise way to divide or moltiply, // note that the X is the number of positions to shift the number y <<= x // Multiplication by 2^x y >>= x // Division by 2^x
Even if is possible only to moltiply/divide number by 0,1,2,4,8,16 and so on, consider that the bitwise function is faster up to 3.5 times of the usual one.
Cast using bitshift
Since the bitwise operation results in an integer value (int or uint) we can use the bitshifter also for casting Number to int (uint)
This is 10% fastwer of the normal casting. This also can be used to emulate the math.floor on a double ;)
// Normal casting x = int(1.232) // casting with bitshifting x = 1.232 >> 0;
Swapping int with the Xor Operator ( ^ )
The Exclusive disjunction, also called exclusive or (symbolized XOR or EOR), is a type of logical disjunction on two operands that results in a value of true if exactly one of the operands has a value of true. A simple way to state this is “one or the other but not both, but i’m sure you still know this. What probably you don’t is this advance and smart use of the XOR.
Assume that x and y are two int (uint) already sets.
x = x ^ y; // x is equal to x^y y is equal to y y = x ^ y; // x is equal to x^y y is equal to (x ^ y )^ y == x x = x ^ y; // x is equal to (x ^ x) ^ y == y y is equal to x
like explained in the comment you actually swap two variables without using an auxiliar one and this is also 1.4x times faster!
Other interesting operations
The modulo operator (%) can be easily replaced by an additive mask (with the AND “&” operator).
In other words, the number we need to use as our mask in order to perform a modulus operation on 2^n is simply 2n – 1. To illustrate this, the following pairs of statements are all equivalent to one another:
x = y % 8; x = y & 7; x = y % 32; x = y & 31; x = y % 256; x = y & 255;
The only difference is that using the mask is 6x faster than the normal modulo.
For the same reason, using this way do determinate if a number is Even or Pair is much faster!
isEven = (i & 1) == 0; // if i is even return true, elsewhere false.
the following one is probably the best one on encreasing performance side, it is 25x faster than the original Math.abs()
//version 1 i = ( x >> 31) ? -x :x; //version 2 i = (x ^ (x >> 31)) - (x >> 31);
Comparing two integers for equal sign
eqSign = a ^ b >= 0;
Sign flipping using NOT or XOR
i = ~i + 1; //or i = (i ^ -1) + 1
So what masks are? they are exactly what you think they are, a way for masking something and show the rest. There are mainly 3 functions on using bitmask:
Masking bits to 1
To turn certain bits on, the bitwise OR operation can be used.Knowing that Y OR 1 = 1 and Y OR 0 = Y. Therefore, to make sure a bit is on, OR can be used with a 1. To leave a bit unchanged, OR is used with a 0.
Masking bits to 0
To change a bit from on to off using the OR operation bitwise AND is used. When a value is ANDed with a 1, the result is simply the original value, as in: Y AND 1 = Y. However, ANDing a value with 0 is guaranteed to return a 0, so it is possible to turn a bit off by ANDing it with 0: Y AND 0 = 0. To leave the other bits alone, ANDing them with a 1 can be done.
Querying the status of a bit
It is possible to use bitmasks to easily check the state of individual bits regardless of the other bits. To do this, turning off all the other bits using the bitwise AND is done as discussed above and the value is compared with 0. If it is equal to 0, then the bit was off, but if the value is any other value, then the bit was on. What makes this convenient is that it is not necessary to figure out what the value actually is, just that it is not 0.
So for exemple if you want to know the value for the 5th bit of a 8-bit number just AND it with a 00010000 mask.
Bitmasks Implementations in as3
The main havy use of bitwise operation in as3 is refeared on handling color data.
As you probably know there are mainly two type of colour on flash the 24 bit (with 3 channel, and 8bit (255 value) for each color channel) and the 32 bit (that add the Alpha channel with its 8 bit value). Working with colors can be really painfull if you don’t keep in mind that they are only bits! So forget substring doublets, forget the 10-base arithmetic and start using what you learn on the lines above.
// EXTRACTING COMPONENTS //24bit var color:uint = 0x336699; var r:uint = color >> 16; var g:uint = color >> 8 & 0xFF; var b:uint = color & 0xFF; //32bit var color:uint = 0xff336699; var a:uint = color >> 24; var r:uint = color >> 16 & 0xFF; var g:uint = color >> 8 & 0xFF; var b:uint = color & 0xFF;
// COMBINING COMPONENTS //24bit var r:uint = 0x33; var g:uint = 0x66; var b:uint = 0x99; var color:uint = r << 16 | g << 8 | b; //32bit var a:uint = 0xff; var r:uint = 0x33; var g:uint = 0x66; var b:uint = 0x99; var color:uint = a << 24 | r << 16 | g << 8 | b;