Archive
This post is archived and may contain outdated information. It has been set to 'noindex' and should stop showing up in search results.
Actionscript 3: Faster Math.floor and Math.ceil using int typecast
Nov 19, 2010ProgrammingComments (2)
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.
Comments (2)
Add a Comment


Please review the commenting policy prior to commenting.
Imran Ar   Feb 01, 2017
in case of Cieling, your algo fails if testVar is already a non decimal (integer)
Nathanael Detlev Petrick   Feb 11, 2016
Did not use this. Once I tested for 1 != 0 to prevent addition to numbers with no decimal places the speed gain was lost.