# JavaScript: Rounding number without impacting result accuracy

The problem: If you do log1000 the result you will get is log1000 = 2.9999999999999996 rather than 3.

I tried to remove this rounding error in the JavaScript eval() function without impacting result accuracy. In the format numbering function FormatNumber(strnum) I put CheckEpsilon(strnum) which tests if the "right tail" of number is greather than epsilon (assuming that the value of epsilon is 1e-9 as in C)

function FormatNumber(strnum) {
// asf - number format: automatic(0), scientific(1) or fixed(2) notation
// decimal - number of decimal places(0-15)

// First we must check if the right tail is bigger than epsilon
strnum = CheckEpsilon(strnum);
// And then we format the number
var x = parseFloat(strnum);

switch(asf) {
case 0:     // auto
strnum = x.toPrecision();
break;
case 1:     // sci
strnum = x.toExponential(decimal);
break;
case 2:     // fix
strnum = x.toFixed(decimal);
break;
}

return strnum;
}

function CheckEpsilon(strnum) {
// EPSILON  - Difference between 1 and the least value greater than 1 that is representable.

var epsilon = 1e-8;
var x = parseFloat(strnum);

var expnum = x.toExponential(17);
// Last 10 numbers before the exponent (9 if the number is negative)
// we turn in to a new decimal number ...
var y = parseFloat("0." + expnum.slice(9,19));

// and then we compare it to epsilon (1e-8)
// If y (or 1-y) is smaller than epsilon we round strnum
if (y<epsilon || (1-y)<epsilon) {
strnum = x.toExponential(10);
}

//and if it isn't, strnum is returned as normal
return strnum;
}

If you're interested in a practical showcase of the function you can take a look at a calculator I made (it's made in javascript so you can check the code easily). The link is: http://www.periodni.com/calculator.html.

This is the way I've done it, however my actual question is: Does anyone know of any better way of doing this?

• "I tried to remove this rounding error in the JavaScript eval() function without impacting result accuracy." eval has nothing to do with it, it's just that IEEE-754 double-precision floating point numbers can't perfectly represent every value. Sep 30, 2013 at 20:22