私は長年にわたり合理的にうまくいった時間計算機を持っています。しかし、いつも気になっていたことは、小数点以下の秒数を使用すると、結果が浮動小数点の「エラー」になる可能性があるということでした。だから、私は最近this BigDecimal libraryを使用するように切り替えました。不正確な除算結果
今、数学的なエラーが発生しています。今日受け取ったバグレポートの単純化されたテストケースです:27436/30418
は、0.9019659412190151
の代わりに1
を返しています。私の問題を説明するために
、ここでChromeのJavaScriptコンソールセッションです:あなたが見ることができるように
> first = 27436
27436
> second = 30418
30418
> first/second
0.9019659412190151 // expected result, but using JS numbers, not BigDecimals
> firstB = new BigDecimal(first.toString())
o
> secondB = new BigDecimal(second.toString())
o
> firstB/secondB
0.9019659412190151 // this is a JS number, not a BigDecimal, so it's susceptible to the problems associated with floating-point.
> firstB.divide(secondB)
o // BigDecimal object
> firstB.divide(secondB).toString()
"1" // huh? Why 1?
> firstB.divideInteger(secondB).toString()
"0"
、divide()
方法は、私が期待する結果を生成されていません。私は何をする必要がありますか?
更新
コメントに応じて、さらに詳しい説明があります。
まず、BigDecimalを使用することは過度の使用であるとの意見がいくつか出されました。そうかもしれませんが、私はその決定を下す前にもっと詳細が必要だと思います。このアプリはtime calculatorなので、私はBigDecimalに切り替えるためにプッシュしたものがいくつかあります。まず、これは電卓なので、ユーザーに正解を示すことが重要です。ユーザーが0.1 s + 0.2 s
と入力した場合、回答は0.3 s
であると予想されます.Javascriptが表示する回答ではありません(0.30000000000000004
)。
JSで使用できる精度を超えて精度を制限したくないので、ユーザーに必要な最大精度がわからないため、整数を使用できます。ほとんどの場合、小数点以下の秒を使用することはありませんが、私が受け取った電子メールから判断すると、いくつかあります。私は現在、すべての時間を秒として内部的に保管しています。
誰かが、数字を正確な分数として保存することを提案しました。残念ながら、私はそれが何を意味するのか分かりません。多分私は数学についてあまり知りません。私は自分の数学図書館を転がすには十分知らない。そのため私はBigDecimalを使用しています。それは長い間されているので、私は問題がBigDecimalのバグに起因すると言っていることを躊躇しています。私はむしろそれが私がそれを使用している方法のバグだと思う。
最後に、私は具体的にBigDecimalに結びついていません。私は、私の不十分な数学スキルでそれらを使うことができるならば、他の提案には開いています。
おそらく、それは精度と関係があります。同様に、精度が小さすぎる場合、最も近い整数に丸められます。また、単純に浮動小数点エラーのためにBigDecimalを使うのは残念です。また、数値を正確な分数として保存することもできます。 – karnok
ええ、BigDecimalを使用すると、あまりにも過剰な私のように見えます。特に、* time *のような固定精度の計算を行う場合は、整数(秒?ミリ秒ですか?)を使用してから、適切な変換を行います。 – redShadow
0.1は、丸め誤差のかなり大きな違いです。また、問題は火かき棒のままです。おそらくバグレポートを提出したいと思うかもしれません。 –