質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

5回答

3655閲覧

3 * 1.3 = 3.9にならない件

Clementine

総合スコア157

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2017/05/26 07:28

編集2017/05/26 07:31

以下の値が、3.9000000000000004になってしまいます。

javascript

1 $('#target').val(3 * 1.3);

これを3.9と正しく計算する方法をご教授ください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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

raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

基本は小数点以下の計算をしないことです。

console.log(3*1.3); console.log(3*13/10);

投稿2017/05/26 07:38

yambejp

総合スコア114572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/05/26 22:30

分かりやすいけど、わかりにくいw
guest

0

解決方法も含めてなぜそうなるかはこちらを一読してください。
JavaScriptでの小数点の計算の誤差について

投稿2017/05/26 07:31

m.ts10806

総合スコア80765

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

多分、みんな一度は疑問に思う(つまり、ハマるw)点ですよね。
言語別?計算誤差に関して
上記は以前私がした質問です。

raccy さんが別の表現で解説してくれています。
多分、後輩に注意しまくっているんで、なれているんでしょうねw
小数点以下の数字を正確に処理することは、自身の作成する数式への理解と、計算機の行う処理への理解の双方が十分でないと、難しいです。

結論として、yambejp さんの回答のように、小数点以下の計算をさせないことが、簡単な解だと思います。

投稿2017/05/26 22:46

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

10桁の文字列にして末尾のゼロを削除とか
$('#target').val((31.3).toPrecision(10).replace(/0$/,'')); //3.9

計算結果が大きな桁だと変な値になりますけどね。

投稿2017/05/26 16:35

hirohiro

総合スコア2068

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hirohiro

2017/05/26 16:53

(3*1.3).toString().replace(/(\d*\.\d*?)000.*$/,'$1'); 小数点の後ろでゼロが3つ以上続いたらそれとその後は削除とか
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問