11

UNIXベースのシステムで問題が発生しました。sprintfが適切に値を切り上げません。

例えば

double tmp = 88888888888885.875
char out[512];

それは88,888,888,888,885.875です。小さい数でうまく機能するように見えるので、私はそのような具体的で大きな例を挙げています。

私はそれを次のように使おうとしています

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

Windowsでは、次のようになります。

out = 000088888888888885.88

たとえばAIXの場合ですが、Linuxでも表示されます。

out = 000088888888888885.87

なぜこうなった?Win /Unixでアイデアとそれを同じように動作させる方法

ありがとう

4

4 に答える 4

1

プロセッサとコンパイラで使用される浮動小数点表現は何ですか?

すべてのプロセッサが浮動小数点値を表すために同じ方法を使用するわけではなく、コンパイラでさえ異なる浮動小数点表現方法を選択する場合があります(Microsoft C ++コンパイラには表現を選択するオプションさえあると思います)。

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

http://msdn.microsoft.com/en-us/library/0b34tf65.aspxは、Microsoft VisualC++が浮動小数点値を格納する方法について説明しています。AIXまたはLinuxで使用されている表現をすぐに見つけることができませんでした。

さらに、すべてのコンパイラには、浮動小数点演算をどのように処理するかを指定できるオプションがあります。それらを可能な限り正確にしますか(ただし、多少遅くなる可能性があります)?または、浮動小数点演算を可能な限り高速にしますか(ただし、正確性は低くなります)?

于 2011-01-10T17:52:15.893 に答える
1

あなたと非常によく似た問題を持つglibcのバグレポートがあります。ここでの主な結論(コメント46)は、doubleは15桁の数字ではなく、そのように機能することを期待すべきではないということです。

回避策として、数値に小さなものを追加して、数値をより適切に丸めることができます。ただし、このソリューションは、処理する番号範囲に依存するため、一般的ではありません。

別の回避策は、丸めの準備をするために乗算してから、丸めることです(例2597.625*100 = 259762.5 -> 259763 = 2597.63*100

ただし、よりスマートな回避策が必要だと思います。

于 2011-01-11T00:55:30.667 に答える
0

doubleこれは、精度に制限のあるものを使用しているためです。つまり、88888888888885.875内部で他の何かに丸められている可能性があります。

同様の質問ブログ、またはウィキペディアで詳細を参照してください。

于 2011-01-10T17:34:29.853 に答える
0

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

于 2011-01-10T17:51:35.337 に答える