- - PR -
丸め誤差の対応について、皆様どうしていますか?
投稿者 | 投稿内容 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-06-02 19:14
数値の有効桁数を決める、とはどういうことなのでしょうか。
決めておけば少数がその位で勝手に丸めが行われるのでしょうか? 当方は特に桁数を設定したりはしてないので、 計算結果がすごい小数点ならそれをそのまま何とかしようとしています。 また、がるがるさんのご指摘で小数点を回避とありますが、 小数点のデータを使用するので逃げられません。 ×10とかで計算、後に÷10とか、そういうことでしょうか? 分からないことばかりですみません。 よろしくお願いします。 | ||||||||||||||||||||||||
|
投稿日時: 2005-06-02 19:56
ものにもよると思います。 1円でも間違ってはいけないようなお金の計算が必要なシステムでは、浮動小数点を使ってはいけませんよね。 | ||||||||||||||||||||||||
|
投稿日時: 2005-06-02 20:47
とりあえず、苦肉の策としてこんなのを思いつきました。
浮動小数点の計算をした結果を整数に丸めるなら まず最大の小数点桁数で丸めます。 例えば小数点2位×整数なら小数点2位まで丸めます。 その値を整数になるように丸めれば、とりあえずは凌げるのかな・・・と。 これはどうですか、皆様。 今後はシビアな計算を求められるものはBigDecimalで持たせることにしようと思ってます。 | ||||||||||||||||||||||||
|
投稿日時: 2005-06-02 23:46
正確な値が必要ないのであればアマさんの最初の案で問題ないと思います。
ちなみにEdossonさんの言われるとおりどんなことをしても10進数と2進数の間の少数の誤差を完全になくすことは絶対にできません。 業務的に誤差が困るのであれば、doubleを利用しないように書き直すほかありません。 | ||||||||||||||||||||||||
|
投稿日時: 2005-06-03 08:16
何ヶ月かしてそのソースを見た時に2回も丸めている理由が思い出せますか? 型変換も伴うでしょうし、2回も丸めるようなややこしいことをするくらいなら、 最初から一貫してBigDecimalを使った方がすっきりして良いのではないでしょうか? 計算式が計算メソッドになるのが難点と言えば難点ですが、正確性には代えられませんよね? | ||||||||||||||||||||||||
|
投稿日時: 2005-06-03 08:49
アマさんこんにちは。
>まず最大の小数点桁数で丸めます。 四捨五入は1回でやらないと結果が違ってくると思います。 このあたりが参考になるのではないでしょうか? http://www.okada.jp.org/RWiki/index.php?JIS%2CISO%BC%B0%BB%CD%BC%CE%B8%DE%C6%FE http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?mode=viewtopic&topic=20401&forum=7&start=0 | ||||||||||||||||||||||||
|
投稿日時: 2005-06-03 09:32
unibon です。こんにちわ。
やりかたとしては、つぎの2つがあると思います。 (1)2進数と10進数の変換誤差が出ないように計算も10進数でおこなう。 (2)表示時に桁数を制限する。 理想は(1)だと思います。Java だと Decimal 関連でしょうか。しかし、これは Java にかぎらずなかなかコストがかかります。CPUのクロックがいくら高くなってもこれがなぜかなかなか はやりません。 一方、(2)のやりかたとしては、ちなみに VB だと1桁少なく表示する、という仕様になっていて Java に比べると 123.00000000001 とか 123.99999999999 みたいなことになりくくくなっています。123.0000000000 や 124.0000000000 になりすなわち 123 や 124 のように表示されます(雰囲気だけ書いてますので桁数などはいいかげんです)。 もっとも勝手に桁数を減らされるのは邪道だと思いますが。 C/C++ でも printf で % で桁数を指定できたと思います。 Java でも 1.5 からは http://www-6.ibm.com/jp/developerworks/java/040423/j_j-tiger04024.html のように Formatter クラスが使えるみたいです。 今後はこれを使うのがいいのではないでしょうか。 もっとも、表示の問題なのか、精度の問題なのかは、要求定義をしっかりしておかないといけないでしょう。場合によっては端数が表示されるほうが本来好ましいケースも少なくないはずです。 | ||||||||||||||||||||||||
|
投稿日時: 2005-06-03 10:23
私は「案件を満たしているなら」と書きましたよ。 「そうすると既に書いてしまったPGが...」なんて心配をしている部分につっこみは無しですか? 案件を満たしていないようなコードなんか、提出しても迷惑なだけでしょう。 ま、私が尖るいわれもありませんが。 だいたい、浮動小数点を使わなかったら誤差を解消できるというわけでも無し。
そもそも、現在取り組んでいらっしゃる案件には、どのような要件があるんですか。 それによって、有効桁数は自ずと決まってくるでしょう。
そんなこと気にしてどうします? 案件を満たすように、プログラミングをするんでしょ?
そんな有様で、案件を満たしているかどうか、どうやって判断するんですか?
この場合、しきい値が0.44と0.45になるのは先にも書いたとおりです。 こんな、切り上げでも切り下げでも四捨五入でもないような処理が正しいんでしょうか? というか、このアルゴリズムを思いついたとき、しきい値がどうなるか考えましたか? その処理の結果が案件を満たすのに貢献するかどうか考えましたか? 誤差の取り扱いは目的ではありません。案件を満たすための手段です。 シビアか否かなんて、人間の主観の問題でしかありません。 完全に一致しなければ、すべて誤差。 重要なのは、案件を満たすために、誤差をどのように扱うかです。 そして、その方法は、「どこの桁で[切り上げ|切り捨て|四捨五入]するか」を決めることそれだけですよ。 どうも、アマさんの投稿をみていると、 案件を棚に上げて、数字をいじくることに終始しているように見えるのですが。 私がよけいなお世話を焼いてるだけなのかな。 |