以下の値が、3.9000000000000004になってしまいます。
javascript
1 $('#target').val(3 * 1.3);
これを3.9と正しく計算する方法をご教授ください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
ベストアンサー
JavaScriptで1.3
というリテラルは 1.3 という十進数の浮動小数点数の値ではありません。
JavaScript
1console.log((1.3).toFixed(20));
つまり、1.3
と書いた時点で正確ではないので、その計算結果も正確であるとは限りません。JavaScriptの数値は、-9007199254740991から9007199254740991までの整数と、2倍を繰り返すと整数になる一部の小数点数だけが正確に表現可能であり、それ以外は近似値であって正確な計算はできないのです。
これは、JavaScriptでの数値がIEEE 754-2008の64ビット倍精度浮動小数点数を表現しているためであり、詳しくは倍精度浮動小数点数について調べてください。
では、どうするのかというと、いくつかの方法があります。
###結果を意味のある精度で丸める。
倍精度浮動小数点数では10進数表記の精度は15桁ほどです。逆に言うと1.3
という数値は15桁までは正確であるとも言えます。ただ、精度の桁数計算(計算結果によって何桁までは正確であると判断するか)は複雑です。どちらかというと、意味がある桁数までしか見ないとした方が有用です。今回の場合は、小数点数2桁目以降は関心が無いとして、丸めることにします。丸めるにはMath.round()
がありますが、整数になってしまいます。ですので、10倍してから10で割ります。
JavaScript
1$('#target').val(Math.round((3 * 1.3) * 10) / 10);
気をつけて欲しいのは3.9
も依然として、 3.9 という十進数の浮動小数点数の近似値にすぎないと言うことに気をつけてください。
実際は、表示の時だけ丸めた方が有用と思います。
###整数として計算する。
1.3
を10倍にして整数にしてしまえば精度の問題は解決します。-9007199254740991から9007199254740991までの整数は正確に計算できるからです。
JavaScript
1$('#target').val((3 * Math.round(1.3 * 10)) / 10);
実際は、最初から最後まで整数としてデータを扱った方が良いと思います。
###任意精度小数点数が扱えるライブラリを使う。
十進数を任意の制度で計算するためのライブラリがあります。それらを使えば問題なく計算できます。ライブラリはいくつかありますが、decimal.jsを使った場合は、次のようになります。
JavaScript
1$('#target').val(new Decimal('3').mul(new Decimal('1.3')).toNumber());
任意精度小数点数は処理が重くなりがちなので、本当に必要な場合は使わない方が良いでしょう。また、精度に関する知識が無いと、正確な精度を把握できません。
###その他
1.3
を13/10という有理数として計算するというのもあります。有理数ライブラリもあるようですので、探してみてください。ただし、有理数計算は総じて重いです。
投稿2017/05/26 22:24
総合スコア21735
0
解決方法も含めてなぜそうなるかはこちらを一読してください。
JavaScriptでの小数点の計算の誤差について
投稿2017/05/26 07:31
総合スコア80850
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
多分、みんな一度は疑問に思う(つまり、ハマるw)点ですよね。
言語別?計算誤差に関して
上記は以前私がした質問です。
raccy さんが別の表現で解説してくれています。
多分、後輩に注意しまくっているんで、なれているんでしょうねw
小数点以下の数字を正確に処理することは、自身の作成する数式への理解と、計算機の行う処理への理解の双方が十分でないと、難しいです。
結論として、yambejp さんの回答のように、小数点以下の計算をさせないことが、簡単な解だと思います。
投稿2017/05/26 22:46
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。