Actionscript 3: Faster Math.floor and Math.ceil using int typecast
Posted November 19, 2010 by Nick Vogt in Programming
In order to use int typecasting in place of Math.floor or Math.ceil, you must first understand exactly what these functions do: Math.floor takes a number and returns the next lowest whole integer. Passing 0.9 will return 0 and -0.9 will return -1. Math.ceil returns the next highest integer, so will return 1 from 0.9 and 0 from -0.9. This is different than truncating, which would return 0 in all cases, and is why typecasting using int (usually used to truncate) wouldn't seem to work at first.

In order to make int typecasting work, you need to add a condition check to see if the number is negative or positive (negative for floor, positive for ceil), and adjust it by 1 if it is. Why do this instead of just using Math.floor or Math.ceil? Because it is faster and you can avoid a function call if desired. Look at these examples:

Using Math.floor like normal requires 691 milliseconds for this run:

var i:int = 0;
var testVar:Number = -82.20035;
var floored:Number;

var time1 = new Date();
for(i = 0; i < 5000000; i ++)
{
  floored = Math.floor(testVar);
}
var time2 = new Date();
trace(time2 - time1);

Now using a custom floor function:

var i:int = 0;
var testVar:Number = 82.20035;
var floored:Number;

var time1 = new Date();
for(i = 0; i < 5000000; i ++)
{
  floored = floor(testVar)
}
var time2 = new Date();
trace(time2 - time1);

function floor(n:Number):Number
{
  if(n < 0) n-= 1;
  return int(n);
}

The above took 601 milliseconds to process. Now you may wonder if the savings are worth the effort of having the extra function, and in some cases I would say no. But that's not where the real performance advantage is to be had. By using int typecasting and the condition, you can avoid the use of a function altogether, and do something like this:

var i:int = 0;
var testVar:Number = 82.20035;
var floored:Number;

var time1 = new Date();
for(i = 0; i < 5000000; i ++)
{
  if(testVar < 0) floored = int(testVar - 1)
  else floored = int(testVar);
}
var time2 = new Date();
trace(time2 - time1);

The above only took 113 milliseconds to process.

Here is the code for finding the ceiling:

if(testVar > 0) ceiling = int(testVar + 1)
else ceiling = int(testVar);

Notice that I checked to see if the original number is greater than 0, and if so added 1.

Comment on this post


Legacy Comments (2)

Nick | February 11, 2011 | 9:14 AM PST
I ran testing using getTimer() and new Date(), and the results varied. Sometimes one was higher than the other. I did find that getTimer() is more accurate for lower amounts (anything under 16ms). I'll try using getTimer() in future tests. Thanks!
Mateusz | February 11, 2011 | 4:00 AM PST
You should use getTimer() to measure execution time;)
Features
Free Web MP3 PlayerComputer Build GuidePHP Beginner Tutorials
Post Series
ActionScript 3 TutorialsHard Drive Cost Charts
Popular Tags
actionscriptajaxcall of dutycrysisebayfacebookgooglejavascriptminecraftneweggphprageskyrimtutorialyoutube


H3XED © 2012 Nick Vogt | Web Design
Saturday, May 19, 2012 | Privacy Policy | Disclosure Policy | Contact