Bitwise gems – fast integer math

Written by MichaelMay 10, 2007

Bitwise operators are very fast in AS3, so here is a small collection of code snippets which can speed up certain computations. I won’t explain what bit operators are and how to use them, rather pointing to an excellent article hosted on gamedev.net: ‘Bitwise Operations in C’.
If you know any good tricks that are not included here, feel free to leave a comment or send me an email. All benchmarks were done in AS3.

Left bit shifting to multiply by any power of two

Approximately 300% faster.

x = x * 2;
x = x * 64;
//equals:
x = x << 1;
x = x << 6;

Right bit shifting to divide by any power of two

Approximately 350% faster.

x = x / 2;
x = x / 64;
//equals:
x = x >> 1;
x = x >> 6;

Number to integer conversion

Using int(x) is 10% faster in AS3. Still the bitwise version works better in AS2.

x = int(1.232)
//equals:
x = 1.232 >> 0;

Extracting color components

Not really a trick, but the regular way of extracting values using bit masking and shifting.

Fast color conversion from R5G5B5 to R8G8B8 pixel format using shifts

89 Comments

Nice article, but your alternate absolute value isn’t exactly right, Math.abs() should return the input number with a positive sign – version 1 only returns 1 or -1. Version 2 only works with integers, that’s not a bug as such but perhaps worth mentioning.

When promoting a R5G5B5 color value to R8G8B8 most just left shift the 5 bit color component value three places. This is will lead to incorrect results. A 5-bit value of 31 (denoting 100%), shifted left three places would be 248. The correct value should be 255.

A quick way to do this using bitwise operations is to perform the left shift, then copy the upper three bits into the lower, zeroed bits after the shift:

R8 = (R5 > 2)

See “Hacker’s Delight” by Henry S. Warren Jr. for more on bitwise operations and integer math.

this is perfectly valid – the signed bitshift operator works only with signed 32bit integers, so MAX_VALUE and 1 are both converted to signed integers first, and so the result is also a signed integer. For unsigned integers use >>>.

so: trace( getQualifiedClassName(uint.MAX_VALUE>>>1) now outputs NUMBER

also, performance loss occurs only when converting between data types.

You are aware that if you’re using a good modern compiler that these will become the exact same machine code as the original mathematical operations, right? The compiler changes any convenient algebraic operations to bit shifts.

So the important thing to do to optimize your code isn’t to use bit shifting, it’s to make sure you’re using a good compiler, and that you try to use powers of two when doing division or multiplication, so that the compiler can use bit shifting in the machine code.

It cut off my comment. Nice. Here’s what I meant to send (LT being less than…): Using what I just read, wouldnÃ¢â‚¬â„¢t it be faster to do something like this for absolute values: i = x LT 0 ? (~x + 1) : x; Or, is that not possible/faster? If so, why?

good idea, I didn’t see that ;-) but ‘i = x < = 0 ? (~x + 1) : x' is not faster than 'i = x < 0 ? -x : x'. I can't tell why, you simply have to try things out and do benchmarks to find the best solution because you don't know how the flash compiler works and how it puts the byte code together.

Only one question. If some of these bitwise operations are so much faster than the standard mathematical operands, how come Flash doesn’t automatically convert the code like this when you compile? Surely the devs were aware of these tricks.

modern compilers in other languages like c++ do a lot of optimizations behind the scenes, but the as3 compiler simply doesn’t offer this kind of optimization, so you have to do it yourself in most situations.

One thing I’m looking for… you only explicity define the variable type in your examples for color math. For my benefit and that of future visitors, it would be great if there was a note regarding int vs. uint for bitwise ops.

This post is amazing, and I’m very glad to see that someone has taken the time to do this. However, I thought I should let you know that “eqSign = a ^ b >= 0;” doesn’t actually check to see if two values are equal in value. I’m guessing it was probably a typo…but just in case.

Say you have the binary values for 10 (1010) and 7(0111). XORING these two values together will provide the following results:

1010 (10)
^0111 (7)
_____
1101 (13)

SO…13(1101) is greater than 0, but 10 and 13 are obviously NOT equivalent in value. Meaning, that the solution should be “eqSign = ((a^b) == 0);”, rather than the suggested version posted above.

Hey dude, this is a really interesting article, thank you very much for sharing these kind of experiments. I think the biggest problem people have is that they always try to use bitwise operators on top of the logic they already have done and it is completely wrong, it needs to be done the other way round, we must build our logic based on these bitwise operators from the very beginning and then our code will look and run completely different. I’ve been involve in a project for validating poker hands using lots of these bitwise operators techniques and I wrote a short article speaking about it, just in case you’re interested on it, it is called The fastest poker hands evaluator ever, thanks for sharing, cheers!

[…] when reading another excellent polygonal labs post on benchmarks and performanceÃ‚Â (this one is great as well concerning faster operations using bit shifts or alternate ways to eek out…)Ã‚Â where he wisely advises to use signed int for loops or iterations rather than uint where needed […]

[…] Bitwise mathematics and shortcuts In my last post I alluded to highly-optimal maths using bitwise (logical) operators, just now (whilst trying to further my own understanding) I found this excellent article on the subject: Polygonal Lab’s Tutorial. […]

[…] 3: Faster Integer Math – Bitwise Operators Several months ago, I stumbled upon a great resource for bitwise operators in AS3. Bitwise math is available in many languages, but this one looks at it from an AS3 […]

[…] If you’re not familiar with bitwise operators I suggest you check out Polygonal Labs’ Bitwise Gems: Fast Integer Math. Done? Great. Okay, on with our discussion. I hope this stuff makes sense because this is my first […]

[…] world. I wanted to share a link to this Polygonal labs post about using bitwise operators to optimize performance in Actionscript 3.0. It’s about a year and a half old, and I haven’t tested out the statements made, but I […]

[…] By thepugilist Hello world. I wanted to share a link to this Polygonal labs post about using bitwise operators to optimize performance in Actionscript 3.0. It’s about a year and a half old, and I haven’t tested out the statements made, but I […]

[…] world. I wanted to share a link to this Polygonal labs post about using bitwise operators to optimize performance in Actionscript 3.0. It’s about a year and a half old, and I haven’t tested out the statements made, but I […]

[…] nice little tips for speeding up Math calculations in Flash by using bitwise maths which I found on labs.polygonal.de. The Math.abs function was one of the most improved and helped speed things up. static public […]

[…] nice little tips for speeding up Math calculations in Flash by using bitwise maths which I found on labs.polygonal.de. The Math.abs function was one of the most improved and helped speed things up. static public […]