2017-03-27 1 views
0

私はここで何かを逃しているに違いないと知っています。私は成功しないで2桁の数字に任意の量を丸めようとしています。このjsfiddleまたはコードでJavascriptの丸数字は、合計で2つを合計すると失敗しますか?

var sumOne = 0; 
var sumTwo = 0; 
[12.993, 12.99, 12.99].forEach(function(number){ 
    sumOne += roundOne(number * 0.1); 
    sumTwo += roundTwo(number * 0.1); 
}) 

function roundOne(n){ 
    return (Math.round((n *100))/100); 
} 
function roundTwo(n){ 
    return +(n.toFixed(2)); 
} 
console.log("sumOne is ", sumOne, " sumTwo is ", sumTwo); 

https://jsfiddle.net/m90ecdh9/1/

私はなぜ、丸めのこれらのメソッドの両方が2つだけ小数点以下との和をもたらすことができないん次の出力

sumOne is 3.9000000000000004 sumTwo is 3.9000000000000004 

で終わるの上?

奇妙なことに、配列内の2つの数字だけでこの同じコードを試した場合、私の結果は、両方の方法で小数点以下2桁の合計で期待どおりになります。

+0

浮動小数点の丸め誤差が発生しています。これは珍しいことではありません。絶対に避ける必要がある場合は、変数に整数型を使用させます。 – IvanSanchez

+0

* roundOne *関数は冗長な括弧を持っています: 'return Math.round(n * 100)/ 100;'が行います。名前は小数点以下2桁まで四捨五入されているので不適切です。 – RobG

+0

参照:[230/100 * 100が230を返さないのはなぜですか?](http://stackoverflow.com/questions/13248173/why-does-230-100100-not-return-230/13248284#13248284)と浮動小数点数学は壊れていますか?*](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – RobG

答えて

0
var sumOne = 0; 
var sumTwo = 0; 
[12.993, 12.99, 12.99].forEach(function(number){ 

    sumTwo += roundTwo(number); // dont *0.1 
}) 

function roundOne(n){ 
    return (Math.round((n *100))/100); 
} 
function roundTwo(n){ 
    return +(n.toFixed(2)); 
} 
console.log("sumOne is ", sumOne, " sumTwo is ", sumTwo); 

https://jsfiddle.net/m90ecdh9/3/

私はsumTwo正しいなりroundTwo(数* 0.1)を除去しました。

なぜこれをやっているのか分かりません。

これは、それぞれの数値を個別に四捨五入して合計します。希望する効果があると私は思います。

丸めたい場合はUPしてください。 toFixed(2)する前に0.05を追加します。小数点以下を切り捨てたい場合は、小数点以下2桁まで切り上げます。

1

浮動小数点精度に問題があります。最も簡単な解決策:

console.log("sumOne is ", sumOne.toFixed(2), " sumTwo is ", sumTwo.toFixed(2))

あなたは1000年によって、あなたの番号も複数のことができますので、彼らは全体の数字になって、それらにあなたの数学演算を行い、その後、再び1000で割ります。

+0

* toFixed *を模倣するために乗算と除算を使うのは良い考えではありません。因数1000を使用すると、100と同じ問題が発生します。なぜ、230/100 * 100は230を返さないのですか?*](http://stackoverflow.com/questions/13248173/why-does-230-100100-not -return-230)丸め誤差は蓄積され、操作の順序によって一貫しない場合があるので、丸めを最後まで残す必要があります。 – RobG

+0

@RobG - しかし230 * 100/100は230を返しませんか?その答えは、計算を行う前に最初に掛け算し、その後分割することを示唆していました。 (明らかに計算にもよるが、途中で小数点以下が得られるかもしれないが、終わりまで丸めを残すことについては同意する) – nnnnnn

+0

@ nnnnnn - 入力が常に小数点以下2桁と算術演算なし分数を生成すると、 '* 100/100'は動作しますが、一般的な解決策ではありません。 – RobG

関連する問題