H3XED

Actionscript 3: Faster Math.floor and Math.ceil using int typecast

Nov 19, 2010   Programming   Nick Vogt   Comments (2)
Please note that this post is over a year old and may contain outdated information.
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.
Share This Post
Twitter

Comments (2)

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.
Share This Post
Twitter
H3XED © Nick Vogt   RSS   Policies   Twitter