Rahul Desai Rahul Desai - 1 year ago 64
Javascript Question

toFixed(2) function not working

This one is weird, because I got it running in this fiddle but it is not working in the main fiddle. I believe the code is the same.

Here is the main function:

for(var i=0; i < companies.length; i++) {
var randomVal = (Math.random()*(10 - (-10) + 1)) + (-10);
randomVal = randomVal / 100;
randomVal = Number(randomVal.toFixed(2));
companies[i].price += randomVal;
//companies[i].price = companies[i].price.toFixed(2);
}, 1000);

A value like
isnt been cut down to
Any idea what is wrong?

Answer Source

This has to do with a common problem that occurs when converting between binary floating point values and decimal representations. See this fiddle, which is like your "working" one, but I altered the price value so that it also breaks.

Here's an even simpler demo that gets right to the heart of the problem: http://jsfiddle.net/2NHSM/4/

As you can see, the output of 1.23 - 1 is 0.22999999999999998. That's obviously off by a little bit, but it has to do with the way computers represent numbers.

Computers hold numbers as binary digits. 1.23 is actually a "repeating decimal" in binary (just like 1/7 is repeating in decimal), so there's no 100% accurate way to store it. As a result, when you subtract 1.23 - 1 you get an answer that is slightly off because 1.23 was never accurate to begin with.

The same thing is happening in your case. To fix it, just use toFixed right before you display the value, not before you add something else to it.


Here's a working fiddle: http://jsfiddle.net/2NHSM/6/

Update 2

Also note that toFixed can have unexpected rounding behavior. Try the following in the console:

// => 1.4
// => 1.4

You might want to use Math.round instead.

Math.round(1.35 * 10) / 10
// => 1.4
Math.round(1.45 * 10) / 10
// => 1.5