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.