double和stringstream格式

Gui*_*e07 11 c++ double

double val = 0.1;
std::stringstream ss;
ss << val;
std::string strVal= ss.str();
Run Code Online (Sandbox Code Playgroud)

在Visual Studio调试器中,val值为0.10000000000000001(因为无法表示0.1).当val使用stringstream转换时,strVal等于"0.1".但是,当使用boost :: lexical_cast时,结果strVal"0.10000000000000001".

另一个例子如下:

double val = 12.12305000012;

在visual studio下val显示为12.123050000119999,并使用stringstream和默认精度(6)它变为12.1231.我真的不明白为什么它不是12.12305(...).

是否存在默认精度,或者stringstream是否有特定的算法来转换无法准确表示的double值?

谢谢.

nic*_*hev 14

您可以更改a的浮点精度,stringstream如下所示:

double num = 2.25149;
std::stringstream ss(stringstream::in | stringstream::out);
ss << std::setprecision(5) << num << endl;
ss << std::setprecision(4) << num << endl;
Run Code Online (Sandbox Code Playgroud)

输出:

2.2515
2.251
Run Code Online (Sandbox Code Playgroud)

请注意在适当的时候数字也是如何舍入的.

  • 使用`std :: setprecision(std :: numeric_limits <double> :: digits10)`来获得完全的双精度. (11认同)
  • 在 Visual Studio C++ 中对此进行测试时,我只能通过先调用 `ss.setf(ios::fixed);` 来使其工作。如果我不这样做,那么精度不会改变。 (2认同)

YuZ*_*YuZ 13

对于任何人谁得到" error: ‘setprecision’ is not a member of ‘std’"你一定#include <iomanip>否则setprecision(17)将无法正常工作!

  • 这应该是评论,或对现有答案的编辑。 (6认同)

Jam*_*nze 5

您必须考虑两个问题。第一个是精度参数,默认为 6(但您可以设置为任何您喜欢的值)。第二个是此参数的含义,这取决于您使用的格式选项:如果您使用的是固定格式或科学格式,则它表示小数点后的位数(这反过来对通常的格式有不同的影响)表示两种格式的精度);但是,如果您使用的是默认精度 ( 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;
Run Code Online (Sandbox Code Playgroud)

看到实际输出可能比任何详细描述都清楚:

default:    0.1
fixed:      0.100000
scientific: 1.000000e-01
Run Code Online (Sandbox Code Playgroud)