## Faster floor, round, ceil for ActionScript

It is always nice to add some speed boost to your performance critical algorithms. Making some native Math function’s alternatives perform up to 8 times faster is possible. Lets have a look at the basic ones Math.floor(), Math.round(), Math.ceil():

faster alternative for Math.floor()

```var ni:int = n;
return (n < 0 && n != ni) ? ni - 1 : ni;```

faster alternative for Math.round()

`return n < 0 ? n + .5 == (n | 0) ? n : n - .5 : n + .5;`

faster alternative for Math.ceil()

```var ni:int = n;
return (n >= 0 && n != ni) ? ni + 1 : ni;```

Here is an app runnig some unit tests and speed tests. I have wrapped both custom methods and Math methods into functions and count out empty method call time to correct the results.

Faster ceil, round, floor – wonderfl build flash online

The results talks for itself:

```Math.floor(): 844 ms
floor(): 125 ms
Math.round(): 859 ms
round(): 109 ms
Math.ceil(): 766 ms
ceil(): 93 ms```

Where to go from here:

## 12 comments so far

1. […] This post was mentioned on Twitter by Klas Lundberg. Klas Lundberg said: RT @jozefchutka: Faster floor, round, ceil for ActionScript http://blog.yoz.sk/2011/01/faster-floor-round-ceil-for-actionscript/ […]

2. pidibi January 11, 2011 great, I love this bitwise magic 🙂

3. pidibi January 11, 2011 sorry, for last comment, is too late – no bit operations was used, but good idea for me to try it …

4. Joe January 19, 2011 Hello,

round doesn’t work for negative values:

trace(round(-12.3), Math.round(-12.3));
trace(round(-12.5), Math.round(-12.5));
trace(round(-12.7), Math.round(-12.7));
trace(round(12.3), Math.round(12.3));
trace(round(12.5), Math.round(12.5));
trace(round(12.7), Math.round(12.7));

// output
-12 -12
-13 -12
-13 -13
12 12
13 13
13 13

5. Jozef Chúťka January 20, 2011 Hi Joe,
thank you for noticing… my tests were running wrong, when working with double-precision floating-points in actionscript there are some glitches like:
for(var n:Number=2;n>=-2;n-=.1) trace(n);
// outputs 2, 1.9, 1.7999999999999998 …
anyway I have updated round() method, and it should work ok now

6. Joe January 20, 2011 Hey, I test it, it works great now!

For your glitches problem, I always use a dec10 function (round At 10 decimal place). It always save my life 🙂

for(var n:Number=2;n>=-2;n-=.1) trace(n, dec10(n));
public function dec10(value:Number):Number
{
return Math.round(value * 10000000000) / 10000000000;
}

7. Jozef Chúťka January 20, 2011 Joe, thnx for the tip

8. Tmr June 27, 2011 Good stuff!
But what does (n | 0) mean in
“return n < 0 ? n + .5 == (n | 0) ? n : n – .5 : n + .5"?
As I understand bitwise OR (x | 0) always produce x. So what the point of doing (n | 0)?

9. Jozef Chúťka June 27, 2011 hi Tmr,
n | 0 removes the decimal part. try 0.5 | 0 or -7.1 | 0

10. Lukasz 'Severiaan' grela November 9, 2011 Hi very nice, but I can improve it a bit:) the round operation surely is missing the | 0 at the end, other wise the fraction stays e.g. 0.512 will be rounded to 1.012

/**
* Faster implementation of round operation
* the “| 0” will remove fraction.
* @author Jozef Chúťka
* @param n
* @return
* @see http://blog.yoz.sk/2011/01/faster-floor-round-ceil-for-actionscript/
*/
public static function round(n:Number):Number
{
return (n < 0 ? (n + .5 == (n | 0) ? n : n – .5) : (n + .5)) | 0;
}

best regards

11. Jozef Chúťka November 9, 2011 Hi Lukasz,
thanks for your suggestion. that totaly makes sense if you use Number as a return type, if you use int you do not need to add | 0

12. Lukasz 'Severiaan' grela November 10, 2011 Hi,
yes indeed, I want my method to match the original Math.round 🙂 and in example there was no casting or indicating of the type,

best regards