double val = 0.1;
std::stringstream ss;
ss << val;
std::string strVal= ss.str();
在Visual Studio调试器, val
具有值0.10000000000000001(因为0.1不能表示)。 当val
使用stringstream的转换, strVal
等于"0.1"
。 然而,使用boost :: lexical_cast的时候,所产生的strVal
是"0.10000000000000001"
另一个例子是下面的:
double val = 12.12305000012;
下视觉工作室val
显示为12.123050000119999,以及使用stringstream的和缺省精度(6)就变成12.1231。 我真的不明白为什么它不是12.12305(...)。
是否有一个默认精度,还是字符串流具有特定算法,可将不能被精确表示的双重价值?
谢谢。
您可以更改的浮点精度stringstream
如下:
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
注意在适当的时候数字是怎么也四舍五入。
对于任何人谁得到“ error: 'setprecision' is not a member of 'std'
”必须#include <iomanip>
其他setprecision(17)
将无法正常工作!
发生在流插入问题ss << 0.1;
而不是在转换为字符串。 如果您想要使用非默认的精度,你需要在插入双指定此之前:
ss << std::setprecision(17) << val;
在我的电脑,如果我只是用setprecision(16)
我仍然得到"0.1"
,而不是"0.10000000000000001"
。 我需要的17(略假的)精确地看到,最后1。
附录
一个更好的示范产生具有1.0 / 3.0的值。 使用默认精度你得到的字符串表示"0.333333"
。 这不是等效字符串的双精度的1/3。 使用setprecision(16)
使字符串"0.3333333333333333"
; 的17精密产生"0.33333333333333331"
。
还有你要考虑的两个问题。 第一个是精度参数,默认为6(但是其可以设置为任何你喜欢)。 第二个是这个参数意味着,这取决于你所使用的格式选项:如果您使用的是固定的或科学的格式,那么就意味着数字的小数点后(其数量又对什么通常是不同的效果在这两种格式通过精密的意思); 如果您使用的是默认的精度,但是( ss.setf( std::ios_base::fmtflags(), std::ios_base::formatfield )
这意味着数字输出的数量,无论输出是否竟是。用科学或固定的符号格式化这就解释了为什么你的显示器是12.1231
,例如:您同时使用默认的精度和默认formattting。
你可能会想尝试不同的值(也许不同精度)以下内容:
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