标准库 to_string(double) 在 vs2015 中给出了错误的值。有什么解决办法吗?

Standard library to_string(double) giving wrong value in vs2015 . Is there any solution?

在Vs2013中to_string函数std::to_string(1.0e+30)提供输出1000000000000000000000000000000.000000.000000

在Vs2015中to_string函数std::to_string(1.0e+30)提供输出1000000000000000019884624838656.000000

如果是标准库问题,是否有可用的修复或补丁?

我搜索了这个问题,遇到了一篇文章解释https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/6xhWgsEuvPo to_string 在 float 或 double conversion 中有错误。

double d = 1.0000000000000000e+30;
std::string s = std::to_string(d);
if (s.length())
{
    s;
}

这里给定值为 1000000000000000019884624838656.000000

预期结果是 1000000000000000000000000000000.000000,在 vs2013 中给出,但在 vs2015 中没有

按照标准,两个都是"correct"个结果。

There are three floating-point types: float, double, and long double. The type double provides at least as much precision as float, and the type long double provides at least as much precision as double. The set of values of the type float is a subset of the set of values of the type double; the set of values of the type double is a subset of the set of values of the type long double. The value representation of floating-point types is implementation-defined. [ Note: This document imposes no requirements on the accuracy of floating-point operations; see also [support.limits]. — end note ]

VS 2015 结果更常见,因为它符合 IEEE 754。根据该定义,1000000000000000000000000000000 不可表示,最接近它的可表示数是 1000000000000000019884624838656

The 53-bit significand precision gives from 15 to 17 significant decimal digits precision.

我真的很惊讶 VS 2013 如何达到 1000000000000000000000000000000。参见 the examples at cppreference

您也可以使用 boost 库中的 lexical_cast 来避免这个问题:

#include <boost/lexical_cast.hpp>

double d = 1.0000000000000000e+30;
std::string s = boost::lexical_cast<std::string>(d);
std:: cout << s;

VS2015 上的结果是:

The value of s is: 1e+30