1

さらに調査した結果、すべては次のようになります。

(decimal)((object)my_4_decimal_place_double_value_20.9032)

2回キャストすると、20.903199999999998になります


Math.Round(...)値が20.9032であるため、小数点以下4桁に丸められるdouble値があります

私の開発環境ではそのまま表示されます。

しかし、リリースされた環境では、20.903199999999998 と表示されます。

後に操作はありませんでしたMath.Round(...)が、値がコピーされて割り当てられました。

これはどのように起こりますか?

更新: データは DB から読み込まれません。

からの戻り値Math.Round()は、元の double 変数に割り当てられます。

この情報が役立つ場合、リリースと開発は同じアーキテクチャです。

4

2 に答える 2

2

IEEE754 倍精度浮動小数点数は 20.9032 を表すことができません。最も正確な表現は 2.09031999999999982264853315428E1 であり、それが出力に表示されます。

double.ToString(string formatString) メソッドの文字列形式を使用する代わりに、数値を round で書式設定しないでください。

Double.ToString メソッド (文字列) のmsdn ドキュメントを参照してください。

リリース ビルドとデバッグ ビルドの違いは、リリース ビルド用に行われる最適化かもしれませんが、これは私の意見では詳細な方法です。私の意見では、中心的な問題は、数学演算でテキスト出力をフォーマットしようとすることです。申し訳ありませんが、詳細に何が異なる動作を作成するのかわかりません。

于 2013-08-06T07:40:59.043 に答える
2

CLR ECMA 仕様によると、次のようになります。

浮動小数点数 (静的、配列要素、およびクラスのフィールド) の格納場所は固定サイズです。サポートされているストレージ サイズは、float32 と float64 です。それ以外の場所 (評価スタック、引数、戻り値の型、およびローカル変数) の浮動小数点数は、内部浮動小数点型を使用して表現されます。このような場合、変数または式の公称型は R4 または R8 ですが、その値は範囲や精度を追加して内部的に表すことができます。内部浮動小数点表現のサイズは実装に依存し、変化する可能性があり、表現される変数または式と少なくとも同じ精度を持つ必要があります。float32 または float64 から内部表現への暗黙的な拡大変換は、これらの型がストレージから読み込まれるときに実行されます。内部表現は通常、ハードウェアのネイティブ サイズ、または操作の効率的な実装に必要なサイズです。

変換すると、生成される IL は同じになります (ただし、デバッグ モードでは、ブレークポイントが可能であることを確認するために場所に nop が挿入されます。リリース モードでは不要と見なされる一時変数が意図的に維持される場合もあります)...ただし、JITter はあまり積極的ではありません。デバッグとしてマークされたアセンブリを扱うとき。リリース ビルドは、より多くの浮動小数点値を 80 ビット レジスタに移動する傾向があります。デバッグ ビルドは、64 ビット メモリ ストレージから直接読み取る傾向があります。

「正確な」浮動小数点数の印刷が必要な場合は、string.Substring(...)代わりに使用しますMath.Round

于 2013-08-06T07:22:16.973 に答える