6

これは奇妙です。このフィドルで実行しましたが、メインのフィドルでは機能していません。コードは同じだと思います。

主な機能は次のとおりです。

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);

isntのような値34.569999999999986はに削減されません34.56。何が悪いのか分かりますか?

4

5 に答える 5

12

これは、2進浮動小数点値と10進表現の間で変換するときに発生する一般的な問題と関係があります。あなたの「働いている」フィドルのようなこのフィドルを見てください、しかし私priceはそれも壊れるように値を変更しました。

問題の核心に迫るさらに簡単なデモを次に示します。http://jsfiddle.net/2NHSM/4/

ご覧のとおり、の出力は1.23 - 1です0.22999999999999998。それは明らかに少しずれていますが、それはコンピューターが数字を表現する方法と関係があります。

コンピューターは数値を2進数として保持します。1.23は実際には2進数の「循環小数」であるため(1/7が10進数で繰り返されるのと同じように)、100%正確に保存する方法はありません。その結果、減算すると、そもそも正確ではなかっ1.23 - 1たため、わずかにずれた答えが得られます。1.23

あなたの場合も同じことが起こっています。これを修正するにはtoFixed、値を表示する直前に使用します。他に何かを追加する前ではありません。


アップデート

これが実用的なフィドルです:http://jsfiddle.net/2NHSM/6/


アップデート2

toFixedまた、予期しない丸め動作が発生する可能性があることにも注意してください。コンソールで次のことを試してください。

1.35.toFixed(1);
// => 1.4
1.45.toFixed(1);
// => 1.4

代わりに使用することをお勧めしますMath.round

Math.round(1.35 * 10) / 10
// => 1.4
Math.round(1.45 * 10) / 10
// => 1.5
于 2012-12-22T02:39:41.573 に答える
3

フローティングポイントは概算であるため、追加しても、必ずしもクリーンな数値になるとは限りません。表示するときにtoFixedを呼び出すだけです。

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

デモ


これがあなた//companies[i].price = companies[i].price.toFixed(2);がうまくいかなかった理由です:

toFixed()文字列を返すため、最初の呼び出しの後はcompanies[i].price文字列になります。を実行するとcompanies[i].price += randomVal;、数値の加算ではなく文字列の連結が実行されます。次のようなものが生成されます。

577.05
577.050.05
577.050.050.1

そのため、次の理由でtoFixedを呼び出すことはできなくなります。

  1. 文字列です
  2. 有効な番号でもありません

それで、どのようにそれを修正しますか?Number()1(または)を掛けて数値に変換します。

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

デモ

これらのソリューションのいずれかを使用すると、への最初の呼び出しtoFixed()は不要です。

于 2012-12-22T02:39:25.377 に答える
1

これは、適用した後.toFixed()、値を別の変数に追加しているためです。これにより、精度が再び低下します。

代わりに、これを表示に使用します。

$('#price'+i).html(companies[i].price.toFixed(2));
于 2012-12-22T02:40:18.827 に答える
0

最初の例で機能する理由は、パスごとに価格の値を577にリセットしているためです。

これを試してください。合計が計算された後、価格に対して.toFixed(2)が呼び出され、変数に返されます。

おそらく、randomValで呼び出された最初の.toFixedを捨てることができます。

 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);
于 2012-12-22T02:56:17.110 に答える
0

変換データは response[25] で、以下の手順に従ってください。

var i = parseFloat(response[25]).toFixed(2)
console.log(i)//-6527.34
于 2016-05-17T11:50:03.100 に答える