1

次の行を含むテキストファイルから読んでいます。

      deltaT          0.005;

文字列内に正しい行を取得したら、次のようなコードで値を読み取りたいと思います。

      double deltaT;
      stringstream ss(line);
      ss >> tag;                //Contains:         deltaT
      ss >> deltaT;             //Should contain:   0.005

デバッグ中に、deltaTに次のものが含まれていることがわかります:0.0050000000000000001

では、ストリームインサーターのようにエクストラクターの「精度」を設定する方法はありますか?

または、テキストファイルの値がプログラムのdouble値であることを保証するための最良の方法は何ですか。

ありがとう、マドレーヌ。

4

2 に答える 2

2

これは、バイナリ浮動小数点型の通常の問題です。0.005は で正確に表現できないdoubleため、「10 進数リテラル」からの変換により、 で表現できる最も類似した数値が得られますdouble

doubleまたは他の有限のバイナリ浮動小数点型を使用する場合、解決策はありません。0.005これは、10 進数では有限形式ですが、2 進数では周期的であるためです (任意の FP 型の仮数は制限されています)。

これがどのように可能であるかを確認するために、分数 1/3 を考えてみましょう: 基数 3 では有限表現を持ち、基数 10 では周期的です。

(1/3) 10 = 0.33333... 10 = 0.1 3

現在、「通常の」浮動小数点型には、仮数 (つまり、格納する有効桁数) のスペースが限られているため、すべての周期数はある時点で切り捨て (実際には丸め) なければなりません。これにより、表示される精度が失われます。

この種の問題に対処し、利用可能なメモリ (たとえばGMP )によってのみ制限される精度で計算を行うために、いくつかの「任意精度ライブラリ」が利用可能であることに注意してください。精度が上がります。

別の解決策 (お金が関係する計算を行うときに一般的に使用される) は、固定精度型を使用することです。これは、金額を何らかの小数係数によって "暗黙的にスケーリングされた" 整数として格納します (概念は、セントをドルの代わりに整数として格納することですfloatまたはなんでもいい); これにより、10 進数から 2 進数への変換に起因する予期せぬ事態が回避されます。これは、すべての整数が任意の基数の限られた桁数で正確に表現できるためです。

于 2012-11-14T22:27:06.803 に答える
0

値を読み取る際の精度に制限などはありません。とにかくそれはしたくありません。可能な限り値の最も近い近似値を取得したいのです。簡単に見ると、これがあなたが得たもののようです!この値0.005は、2 進浮動小数点で正確に表現できる値のようには見えません。型doubleとその仲間は (-1)符号*仮数*2指数として表され、これがすべての 10 進数値を表すことができないことはすぐに明らかです

問題はフォーマットに関するものです。フォーマットする桁数をフォーマットで選択できるようにする必要があります。元の値が何らかのソースから読み取られたばかりで、何らかの計算の結果ではなく 10 進数であると仮定すると、フォーマット時に元の値を取得する必要があります (つまり、末尾のゼロを除く)。

于 2012-11-14T22:34:20.490 に答える