KyuR1 Blog

この上無く不定期更新。

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

PageTop

Help me.

http://codepad.org/Nw2Cb7Ji(剰余を求めるプログラム)

助けて。理由が分からない。
どちらも余りが0になるのが適切なのになぜ!
スポンサーサイト

PageTop

コメント


管理者にだけ表示を許可する
 

No title

まず、浮動小数点の演算は精度が落ちる場合があります。
double型の表現の関係上、0.1を表現しきることは不可能ですが、近似値を表現することは可能です。

fmodの実装を見たところ、以下の通りになるそうです。
double myfmod(double x, double y){
int n = x/y;
return x - (n*y);
}

x/yの結果をint型に変換するとなぜか52になってしまいます。
これはdouble型の精度に関係しており、見かけ上は53であっても、実際の内部表現では52.9999...という形になっています。
ためしに、C++ならば#include <cstdio>をインクルードして、
printf("%f / %f = %.20f n", A, B, A/B);
とすると、誤差が確認できると思います。
そしてint型への変換は例外なく小数部を切り捨てるため、52.9999...は52となります。
そのため、fmodでは5.3-52*0.1が行われ、0.1が出力結果として得られます。

独自の方式のほうでもループ中に同じように
printf("%.20f n", A);
とすると、正確に0.1を減算しているわけではないことがわかります。

精度が高い演算結果を求めるのであれば、
任意精度演算ライブラリを使うか、小数を用いないようにするべきです。
小数演算は専用回路(FPU)を使っても整数演算と比べコストが高いので、
今回のように何回もループさせるような計算に小数を採用するのは実効速度の低下を招くのでオススメしません。

これで間違ってたこと言ってたら恥ずかしい><

ryozi | URL | 2010-05-05(Wed)21:06 [編集]


No title

.>Ryozi
おお・・なるほど・・、よく分かりました。
このような結果になるのは誤差が原因なんですね・・・。
浮動小数点数というものをよく理解していませんでした。
丁寧にありがとうございます。

KyuR1 | URL | 2010-05-06(Thu)19:50 [編集]


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。