3

デバッグするとき、関数から返された浮動小数点数を出力して、それを別の関数の入力値として使用したいことがあります。浮動小数点数のフォーマットをガイドするデフォルトのパラメーターは何ですか。

次のコードで f1 と f2 は常に同じですか?

#include <sstream>
#include <cassert>
int main(int argc, const char *argv[])
{
  std::stringstream ss;

  float f1 = .1f;
  ss << f1;

  float f2;
  ss >> f2;

  assert(f1 == f2);
  return 0;
}

一連の浮動小数点数を std::cout または std::ofsteam に書き込み、それらを読み戻してまったく同じ数値を取得できますか、または小数点の後に数値の量を明示的に設定する必要があります (ここで提案されているように?

私が気になるのは、.1 は 2 進分数として表現できませんが、標準ストリームによって正しくフォーマットされていることです。

4

3 に答える 3

6

必ずしも。デフォルトでは、ostream6 桁の精度で出力されます。float を「往復」できるようにするには、精度が必要ですstd::numeric_limits<float>::max_digits10(最も一般的な表現では 9 です)。ストリームが永続化のために使用されていて、float のみを永続化している場合は、何かを書き込む前に精度を設定するだけです。次に例を示します。

ss.precision( std::numeric_limits<float>::max_digits10 );

( と の両方を処理する必要がありfloatdoubleに余分な桁を入れたくないfloat場合は、浮動小数点値を出力するたびに精度を設定する必要があります。)

于 2013-04-11T15:56:23.843 に答える
1

いいえ、同じであるとは限りません。

何が起こっているかというと、float 自体がデフォルトで出力される精度よりも高い精度を持っているため、読み込んだものの有効桁数がデフォルトの出力精度よりも少ない限り、出力したものは (少なくとも通常は) 丸められます。読み込んだ値に戻ります。

ただし、 の完全な精度を使用するデータがありfloat、それを読み取ってから完全な精度で書き戻すと、違いが見え始めます。

#include <sstream>
#include <iomanip>
#include <iostream>

int main() { 
    std::istringstream buffer("0.1");
    float value;
    buffer >> value;
    std::cout << value << "\n"; 
    std::cout << std::setprecision(10) << value;
}

結果:

0.1
0.1000000015

この場合、末尾15は (およそ) 0.1 と、コンパイラの float が表すことができるそれに最も近い近似値との差です。

于 2013-04-11T16:01:40.467 に答える
-1

さらに重要なことは、assert(f1 == f2); f1 と f2 が両方とも浮動小数点数である場合は、めったに正しくありません。assert(abs(f1 - f2) < tolerance); のようなものが必要です。公差を選択するために一般的に使用される手法がいくつかあります。どちらを使用するかは、プログラムが対処している問題によって異なります。

于 2013-04-11T16:00:47.883 に答える