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 00:47

    great, I love this bitwise magic 🙂

  3. pidibi January 11, 2011 00:49

    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 19:35

    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 00:32

    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 11:32

    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 18:46

    Joe, thnx for the tip

  8. Tmr June 27, 2011 08:46

    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 09:53

    hi Tmr,
    n | 0 removes the decimal part. try 0.5 | 0 or -7.1 | 0

  10. Lukasz 'Severiaan' grela November 9, 2011 13:10

    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 14:58

    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 15:13

    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

Leave a comment

Please be polite and on topic. Your e-mail will never be published.