最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - toFixed(2) function not working - Stack Overflow

programmeradmin4浏览0评论

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:

window.setInterval(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);
        $('#price'+i).html(companies[i].price);
    }
}, 1000);

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

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:

window.setInterval(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);
        $('#price'+i).html(companies[i].price);
    }
}, 1000);

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

Share Improve this question edited May 3, 2016 at 5:12 Rahul Desai asked Dec 22, 2012 at 2:32 Rahul DesaiRahul Desai 15.5k20 gold badges88 silver badges144 bronze badges
Add a comment  | 

5 Answers 5

Reset to default 13

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.


Update

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.35.toFixed(1);
// => 1.4
1.45.toFixed(1);
// => 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

Floating points are approximations so when you add, they don't always end up clean numbers. Just call toFixed when you display it:

companies[i].price += randomVal;
$('#price'+i).html(companies[i].price.toFixed(2));

Demo


This is why your //companies[i].price = companies[i].price.toFixed(2); didn't work:

toFixed() returns a string, so after the first call, companies[i].price is a string. When you do companies[i].price += randomVal;, it is doing string concatenation instead of numeric addition. It'll produce something like:

577.05
577.050.05
577.050.050.1

So you can't call toFixed on it anymore because:

  1. It's a string
  2. It's not even a valid number

So, how would you fix that? Convert it to a number by multiplying by 1 (or Number());

companies[i].price += randomVal;
companies[i].price = companies[i].price.toFixed(2)*1;
$('#price'+i).html(companies[i].price);

Demo

With either of these solutions, the first call to toFixed() is unnecessary.

That's because after applying .toFixed() you're adding the value to another variable, which then causes the precision to go haywire again.

Instead use this for displaying:

$('#price'+i).html(companies[i].price.toFixed(2));

The reason it works in your first example is because you are resetting the value of price to 577 on each pass.

Try this, it calls .toFixed(2) on the price after the sum has been calculated and also returns it back to your variable.

You can probably ditch the first .toFixed thats called on randomVal.

 window.setInterval(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 = Number(companies[i].price.toFixed(2)); 
        $('#price'+i).html(companies[i].price);
    }
}, 1000);

your conversion data is response[25] and follow the below steps.

var i = parseFloat(response[25]).toFixed(2)
console.log(i)//-6527.34
发布评论

评论列表(0)

  1. 暂无评论