2011-10-19 17 views
3

Calculusクラスのリーマン和を使った統合プログラムを実行しています。私は積分を計算する際にCを使用することに決めました。私はこの問題から派生した私のプログラムの大きな誤りに気付きました。 Cの倍精度の精度で有効数字50桁が正しく表示されない

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 

int main(int argc, char** argv) { 

double x = 2.0/20.0; 
printf("%1.50f \n", x); 


return (EXIT_SUCCESS); 
}  

プログラム

は私を与える:0.10000000000000000555111512312578270211815834045410。私の質問:なぜこれが起こるのですか?そして私はこれをどのように修正できますか?または少なくとも小数点第15位まで四捨五入?

ありがとうございました。浮動小数点の

+1

「%1.50f」は小数点以下50桁まで丸めます。なぜなら、これらの無邪気な結果が最初に表示されているからです... –

+5

[すべてのコンピュータ科学者が知っておくべきこと]浮動小数点演算について」(http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html)および第4章 - ドナルド・クヌスの第2巻の算術[コンピュータ・プログラミングの技術](http://www.amazon.com/Art-Computer-Programming.../dp/0201896842)。 –

答えて

7

基礎:あなたのケース0.10

http://en.wikipedia.org/wiki/Floating_point

答えはバイナリ浮動小数点で正確に表現することができません。したがって、それは約16桁までしか正確ではありません。しかし小数点以下50桁まで印刷しようとしています。

+0

それは理にかなっています。どういうわけか、小数点以下16桁に値を丸めることはできますか? – user992711

+0

''%1.50f \ n "'の50を ''%.16f \ n "'のような正真正銘の数字に変更してください。それはあなたが持っている番号のために働く;より大きいまたは小さいマグニチュードの数値に対しては、 '%e'または'%g'形式のほうがよいかもしれません。 –

+0

ナンバー自体はバイナリ形式で保存されているため、四捨五入することはできません。しかし、 '%1.16f'で印刷したときに丸めることができます。 16桁の数字はすでに「倍精度」が保持できるものよりわずかに多く、他の丸め誤差は言及していません。したがって、16桁の数字を印刷すると、最後の数字に「ノイズ」が残ることがあります。 – Mysticial