My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.
Showing posts with label Math. Show all posts
Showing posts with label Math. Show all posts

Sunday, October 04, 2009

[Q&D] Fix Decimal Module Operator

This is a Q&D solution for some JavaScript precision problem when we use the module operator with floating point numbers.

The Problem

If we are dealing with the module operator we could have this case:
alert(
8.25 % .05
);
// 0.049999999999999545

We expected 0 but we have a floating point inconsistency instead. This is a well known problem, and not only with JavaScript, truly annoying when we have to show run-time computed money/trends operations.

The Solution

This comes from my reply in a JS forum, knowing that the module will be a simply floating point, let's say .1 to .001, if we remove floating point from the right side of the operation everything works just fine:

function mod(num, mod){
// Another WebReflection silly idea
var pow = Math.pow(10, (("" + mod).split(".")[1] || "").length);
return ((num * pow) % (mod * pow)) / pow;
};

alert(
mod(8.25, .05)
); // 0


alert(
mod(8.25, .1)
); // 0.5

That's it, have a nice Sunday

Thursday, June 05, 2008

Two simple tricks in JavaScript ( olds, but always useful )

This is a quick post about two really common pieces of code that are used daily from libraries developers and not.

Stop to use Math.floor


The first one is about usage of Math.floor. It is probably only my opinion, but it seems that Math.floor is used always to perform the same task:

var centerWidth = Math.floor((something + someelse - someother) / 2);

The point is that at the end of a Math.floor, you will often find that division by 2.
There is a truly simple way to write less, and to obtain best performances as well, it is the right side bitwise operator, that for this purpose is nearly perfect.

var centerWidth = (something + someelse - someother) >> 1;

That's it! If you compare above examples you will note that second one is about 2X faster than Math.floor.

for(var i = 0, t1 = new Date; i < 50000; i++)
Math.floor(i / 2);
t1 = new Date - t1;

for(var i = 0, t2 = new Date; i < 50000; i++)
i >> 1;
t2 = new Date - t2;

alert([t1, t2].join("\n"));


A tricky String.indexOf


Another common piece of code you can find wherever, is this one:

if(myWord.indexOf(myChar) >= 0) ...

if(-1 < myWord.indexOf(myChar)) ...

if(myWord.indexOf(myChar) !== -1) ...

There is an operator that inverts the number, adding +1, and that is perfect every time we have a function that could return 0, more than zero, or -1 where there's no match.

if(~myWord.indexOf(myChar)) ...

Above example converts every number from 0 to N into -1 to -(N+1)
Accordingly, if the result is -1, the result will be zero -(-1+1), where -0 does not make sense in JavaScript, and it is simply threaded as 0 (no limits guys :D)

The latter one is probably not known as the first one, and its execution time is about the same, but you write less, and you can recognize instantly if that method or function respect the integer -1 to +N return value.
The implicit cast when you use an if or a ternary operator, is the one that makes that check fast enough, but not faster than common way as is the first suggested trick.

P.S. these tricks could be used with many other program languages ;)