2011-01-10 13 views
9

UNIXベースのシステムで問題があります。sprintfは正しく値を切り上げません。 88,888,888,888,885.875ザッツWindowsとsprintfのUnixベースのシステムでの丸めの違い

例えば

double tmp = 88888888888885.875 
char out[512]; 

ちょうど目に容易になります。 小さな数字でうまくいくように見えるので、私はそのような具体的で大きな例を挙げています。 Windows上で

私は、次の方法でそれを使用しようとしています

sprintf(out, "%021.2f", tmp); 
printf("out = %s\n", tmp); 

これは、その結果:例えばAIX上で

out = 000088888888888885.88 

が、同様にLinuxでのショー:

out = 000088888888888885.87 

なぜこれが起こっていますか? 任意のアイデアとどのようにそれが勝利/ Unix上で使用すると、精度の限界、意味を持つdoubleを使用しているためだ

おかげ

+2

erm、http://www.ideone.com/UVtftは '.88'を報告します。私のローカルSuseLinuxは同じことを報告しています... – Nim

+3

各OSにはどのようなCPUを使用していますか? – chrisaycock

+0

Linux(Debian 5)AMD64で '000088888888888885.88'を取得しました –

答えて

1

glibcにはbug reportがあります。問題はあなたと非常に似ています。ここでの主な結論(コメント46)は、doubleは15桁の数字ではなく、そのように動作するとは期待してはいけません。

回避策として、あなたの数字に小さなものを追加してより円滑にすることができます。しかし、この解決法は、扱う数値範囲に依存するため、一般的ではありません。

別の回避策は、私が賢く回避策がなければならないと思いますが(例えば2597.625*100 = 259762.5 -> 259763 = 2597.63*100

を丸め、その後、丸めのためにそれらを準備するために掛けることができます。

+0

私はあなたの回避策を使用しませんでしたが、私が必要としたのは、ありがとう – grobartn

0

を同じように動作させるためには、あなたの88888888888885.875は、おそらく内部的に何か他のものに丸められています。

in a similar questionを参照してください。blogsまたはwikipediaです。

+3

はい、異なるOS上で二重丸めが異なるのはなぜですか?もちろん、正確さの限界があるので、彼は別の答えを得ています。 – Grammin

+2

これは、ボックスのアーキテクチャによって、libcのprintfによって行われるいくつかの研磨までさまざまです。同じOS(Linux)内であっても、コメントから質問にわかるように、動作は同じでなければならないという保証はありません。 –

0

IEEE 754準拠の実装では、デフォルトの丸めモードで88888888888885.88を出力する必要があります。値は正確に表現可能であるため、これは浮動小数点精度とは関係ありません。小数点以下2桁に丸めるのはprintfの問題です。一部のシステムで88888888888885.87が表示される理由は考えられません。

+1

OPは、 'printf'でこれが起こっていることを確認するために、' sprintf'を省略して(そして単にdoubleに直接代入する)のが好きかもしれません。 – Cascabel

1

プロセッサとコンパイラはどのような浮動小数点表現を使用していますか?

すべてのプロセッサが同じ方法で浮動小数点値を表現するわけではなく、コンパイラによっても異なる浮動小数点表現方法が選択される可能性があります(Microsoft C++コンパイラでもその表現を選択するオプションがあります)。

ページhttp://www.quadibloc.com/comp/cp0201.htmは、いくつかの浮動小数点表現の概要を示しています(ただし、そこにはかなり古いアーキテクチャのようです)。

http://msdn.microsoft.com/en-us/library/0b34tf65.aspxは、Microsoft Visual C++が浮動小数点値をどのように格納するかを示します。 AIXやLinuxでどのような表現が使われているのかはすぐにはわかりませんでした。

すべてのコンパイラには、浮動小数点演算の使用方法を指定できるオプションがあります。あなたはそれらを可能な限り正確にしたいですか(しかし多少遅いかもしれません)?または、浮動小数点演算を可能な限り速くしたい(ただし、あまり正確でない可能性があります)か?

+0

MSVCは表現を選択できません。オプションは浮動小数点の算術および方法で実行される最適化に関するものです。 – Puppy

+0

興味深い関連する質問があります:http://stackoverflow.com/questions/1961442/different-math-rounding-behaviour-between-linux-mac-os-x-and-windows – mizo

関連する問題