# 2 posts on Math

## Extend Math.log to allow for bases != e

1 min read 0 comments

As Math.log currently stands, itâ€™s a bit useless. It only calculates natural logarithms (base e).Â  We can easily modify it however, to calculate logarithms of any base:

``````Math.log = (function() {
var log = Math.log;
return function(n, a) {
return log(n)/(a? log(a) : 1);
}
})();
``````

We can now specify the base as a second parameter, or still use the default one (Math.E) if we donâ€™t specify one, so older scripts wonâ€™t break or if we want a shortcut to the natural logarithm. ;)

## Extend Math.round, Math.ceil and Math.floor to allow for precision

3 min read 0 comments

`Math.round`, `Math.ceil` and `Math.floor` are very useful functions. However, when using them, I find myself many times needing to specify a precision level. You donâ€™t always want to round to an integer, you often just want to strip away some of the decimals.

We probably all know that if we have a function to round to integers, we can round to X decimals by doing `Math.round(num*Math.pow(10,X)) /` `Math.pow(10,X)`. This kind of duck typing can get tedious, so usually, you roll your own function to do that. However, why not just add that extra functionality to the functions that already exist and youâ€™re accustomed to?

Letâ€™s start with `Math.round`. Itâ€™s the most needed one anyway.

Firstly weâ€™ll have to store the native function somewhere, since weâ€™re going to replace it. So we do something along the lines of:

``````Math._round = Math.round;
``````

Now letâ€™s sigh replace the native `Math.round` with our own:

``````Math.round = function(number, precision)
{
precision = Math.abs(parseInt(precision)) || 0;
var coefficient = Math.pow(10, precision);
return Math._round(number*coefficient)/coefficient;
}
``````

And guess what? It still works the old way too, so your old scripts wonâ€™t break.

So now, letâ€™s go to `Math.ceil` and `Math.floor`. If you notice, the only thing that changes is the function name. Everything else is the same. So, even though we could copy-paste the code above and change the names, we would end up with triple the size of the code that we need and we would have also violated the DRY principle. So we could put the names of the functions in an array, and loop over it instead:

``````(function(){
var MathFns = ['round', 'floor', 'ceil' ];
for(var i = MathFns.length; i>-1; i--)
{
Math['_' + MathFns[i]] = Math[MathFns[i]];
Math[MathFns[i]] = function(number, precision)
{
precision = Math.abs(parseInt(precision)) || 0;
var coefficient = Math.pow(10, precision);
return Math['_' + MathFns[i]](number*coefficient)/coefficient;
}
}
})();
``````

Why the closure? To allow us to be free in defining our variables without polluting the global namespace. In case `Array.prototype.forEach()` was cross-browser or if you have mutated the `Array` prototype to add it for non-supporting ones, you could easily do that:

``````['round', 'floor', 'ceil' ].forEach(function(funcName){
Math['_' + funcName] = Math[funcName];
Math[funcName] = function(number, precision)
{
precision = Math.abs(parseInt(precision)) || 0;
var coefficient = Math.pow(10, precision);
return Math['_' + funcName](number*coefficient)/coefficient;
}
});
``````

No closures and much easier to read code.

However, nothing comes without a cost. In this case, the cost is performance. In my tests, the new function takes about twice the time of the native one. Adding a conditional to check if the precision is falsy and use the native function directly if so, doesnâ€™t improve the results much, and it would slow the function down for precision values > 0. Of course the speed would be just as much if the function was a normal one and not a replacement for Math[something], that doesnâ€™t have anything to do with it.