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

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

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

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

Q&A

解決済

3回答

1496閲覧

JavaScriptの循環小数の計算について

airulove

総合スコア35

JavaScript

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

0グッド

0クリップ

投稿2017/09/15 09:51

角度を扱う計算プログラムをJavaScriptで開発しています。
角度は度分秒単位で結果を表示しています。

90°25´44″

という感じに表示しています。

秒単位の小数点以下は四捨五入して表示しているのですが、計算結果が循環小数の場合だと、計算結果が電卓の結果と異なってしまいます。

電卓で

1/3*3

という計算を行うと 1 という結果になります。循環小数は加味しない結果になっているのでしょうか。

しかし、JavaScriptの場合、

0.99999999999.......

という結果になってしまいます。

秒の結果が電卓だと 15.5″ だとしても、

JavaScriptの場合だと 15.4999999999....″ となってしまい、四捨五入すると結果が異なってしまいます。

循環小数を加味しない計算結果を求めるにはどうすれば良いでしょうか?

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

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

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

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

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

kei344

2017/09/15 11:34

テスト用のコードを提示してください。
guest

回答3

0

ベストアンサー

浮動小数点演算

JavaScriptの基本仕様(ECMAScript)では浮動小数点演算を IEEE 754 に準拠しており、小数を伴う演算で正確な値を出すことが出来ません。
ですので、小数演算で正確な値を出す場合には文字列で数式を与えて、内部的に整数演算で処理する事で値を割り出すようなギミックが必要になります。

とはいえ、毎回上のような文字列処理を行うのはコストが高くつくので、通常は整数演算してから10の乗数で除算して対応します。

JavaScript

1console.log(0.6 * 3); // 1.7999999999999998 2console.log(10 * 0.6 * 3 / 10); // 1.8

循環小数

1/3*3
という計算を行うと 1 という結果になります。循環小数は加味しない結果になっているのでしょうか。

JavaScript は循環小数も解釈しません。
この計算式であれば、次のように計算順を書き換えてやる対策が一般解となります。

JavaScript

1console.log(1*3/3); // 1

それでも、1/3*3 === 1 になるようなコードを書くとするなら、先程と同様に文字列で数式を渡し、内部的に計算順を入れ替えてやるギミックが必要になるでしょう。

(2017/09/19 21:12追記)

eval-calculation-0.9.2.js で除算に先んじて乗算するように処理を変更しました。

eval-calculation-0.9.1.js 当時でも正常に動作しているように見えますが、最近のブラウザは 0.3333333333333333 * 3=== 1 が成立するようです。
というわけで、airulove さんがどの実装(ブラウザ等)で 1/3*3 を "0.99999999999......." と評価されたのか、気になるところです。

Re: airulove さん

投稿2017/09/16 11:58

編集2017/09/19 11:11
think49

総合スコア18162

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

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

0

javascriptの仕様に詳しくはないので一般論で答えます。

コンピュータで処理する以上、データは有限のメモリによって記録できるものでなければなりません。したがって、無限の精度を実現することは不可能です。

もちろん、分子と分母をそれぞれ個別に管理すれば(有理数について)これに近いことはできます。が、結局無限精度にはなりません(極端に大きい数や無理数)。あらかじめ許容誤差範囲を定める等の妥協的な方法が必要となります。

この他、(計算途上だけ有理数化したとしても)最終的なアウトプットフォーマットやセンサーの精度といった別件の問題もあるので数値処理の中でこのような方法を使うことはあまり見られません。

投稿2017/09/15 10:56

HogeAnimalLover

総合スコア4830

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

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

0

確認ができないのでコードを教えていただけると!
イメージ説明

投稿2017/09/15 10:00

MasakazuFukami

総合スコア1869

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

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

m.ts10806

2017/09/15 10:16

回答ではなく「追記・修正依頼」に書くべきかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問