Para los amantes de las matemáticas: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
Lo recomendable es utilizar factores de corrección (multiplicar por una potencia de 10 adecuada para que la aritmética se realice entre números enteros). Por ejemplo, en el caso de 0.1 * 0.2
el factor de corrección es 10
y estás realizando el cálculo:
> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> (x * cf) * (y * cf) / (cf * cf)
0.02
Una solución (muy rápida) sería algo así:
var _cf = (function() {
function _shift(x) {
var parts = x.toString().split('.');
return (parts.length < 2) ? 1 : Math.pow(10, parts[1].length);
}
return function() {
return Array.prototype.reduce.call(arguments, function (prev, next) { return prev === undefined || next === undefined ? undefined : Math.max(prev, _shift (next)); }, -Infinity);
};
})();
Math.a = function () {
var f = _cf.apply(null, arguments); if(f === undefined) return undefined;
function cb(x, y, i, o) { return x + f * y; }
return Array.prototype.reduce.call(arguments, cb, 0) / f;
};
Math.s = function (l,r) { var f = _cf(l,r); return (l * f - r * f) / f; };
Math.m = function () {
var f = _cf.apply(null, arguments);
function cb(x, y, i, o) { return (x*f) * (y*f) / (f * f); }
return Array.prototype.reduce.call(arguments, cb, 1);
};
Math.d = function (l,r) { var f = _cf(l,r); return (l * f) / (r * f); };
En este caso:
> Math.m(0.1, 0.2)
0.02
Definitivamente recomiendo utilizar una biblioteca probada como SinfulJS