17
double val = 0.1;
std::stringstream ss;
ss << val;
std::string strVal= ss.str();

Visual Studio デバッガーでvalは、値は 0.10000000000000001 です (0.1 を表すことができないため)。がvalstringstream を使用して変換されると、strValは と等しくなり"0.1"ます。ただし、boost::lexical_cast を使用すると、結果strVal"0.10000000000000001".

別の例は次のとおりです。

double val = 12.12305000012;

Visual valStudio では 12.123050000119999 と表示され、stringstream とデフォルトの精度 (6) を使用すると 12.1231 になります。12.12305(...) ではない理由がよくわかりません。

デフォルトの精度はありますか、または stringstream には、正確に表現できない double 値を変換する特定のアルゴリズムがありますか?

ありがとう。

4

4 に答える 4

19

stringstream次のように、aの浮動小数点精度を変更できます。

double num = 2.25149;
std::stringstream ss(stringstream::in | stringstream::out);
ss << std::setprecision(5) << num << endl;
ss << std::setprecision(4) << num << endl;

出力:

2.2515
2.251

必要に応じて、数値も四捨五入されていることに注意してください。

于 2012-10-15T11:55:10.230 に答える
5

考慮しなければならない問題が 2 つあります。1 つ目は精度パラメーターで、デフォルトは 6 です (ただし、好きな値に設定できます)。2 つ目は、このパラメーターの意味であり、使用している形式オプションによって異なります。固定形式または指数形式を使用している場合は、小数点以下の桁数を意味します (通常、 2 つの形式の精度を意味します); ただし、デフォルトの精度を使用している場合 ( 、出力が実際に科学表記法または固定表記法を使用してフォーマットされているかどうかに関係なく、出力のss.setf( std::ios_base::fmtflags(), std::ios_base::formatfield )数を意味します。たとえば、ディスプレイが である理由を説明します。両方を使用しています。デフォルトの精度とデフォルトのフォーマット。12.1231

異なる値 (および異なる精度) で次のことを試してみてください。

std::cout.setf( std::ios_base::fmtflags(), std::ios_base::floatfield );
std::cout << "default:    " << value[i] << std::endl;
std::cout.setf( std::ios_base::fixed, std::ios_base::floatfield );
std::cout << "fixed:      " << value[i] << std::endl;
std::cout.setf( std::ios_base::scientific, std::ios_base::floatfield );
std::cout << "scientific: " << value[i] << std::endl;

実際の出力を見ると、詳細な説明よりも明確になるでしょう。

default:    0.1
fixed:      0.100000
scientific: 1.000000e-01
于 2012-10-15T13:07:15.713 に答える
4

ss << 0.1;この問題は、文字列への変換時ではなく、ストリームの挿入時に発生します。デフォルト以外の精度が必要な場合は、double を挿入する前にこれを指定する必要があります。

ss << std::setprecision(17) << val;

私のコンピューターでは、使用しただけsetprecision(16)"0.1"は、"0.10000000000000001". 最終的な 1 を確認するには、17 の (少し偽の) 精度が必要です。

補遺
1.0/3.0 の値を使用すると、より良いデモが発生します。デフォルトの精度では、 の文字列表現が得られます"0.333333"。これは、倍精度 1/3 に相当する文字列ではありません。を使用setprecision(16)すると、文字列が作成されます"0.3333333333333333"。17 の精度で が得られ"0.33333333333333331"ます。

于 2012-10-15T11:43:49.427 に答える