我想将double值转换为std::string。目前我正在写

return std::to_string(double_value);


但这只返回7位数字,因为内部to_string()仅将std::vsnprintf%f格式说明符一起使用(另请参见here)。

我现在可以使用std::vsnprintf作为格式说明符手动调用%.15f,但这会导致尾随零。

我的目标(在我看来非常明显)现在是采用这样的方法:

string o1 = to_string(3.14)
string o2 = to_string(3.1415926536)
assert(o1 == "3.14")
assert(o2 == "3.1415926536")


Here是从%.20输出修整尾随零的一个很好的阐述,但是这个答案大约有8年的历史了。

也许情况已经变了?今天可以在C ++中以双精度转换double而不用尾随零吗?

解:

根据2man的答案,您可以编写如下通用函数:

template<typename T>
inline std::string tostr(T value) {
    std::ostringstream s;
    s.precision(std::numeric_limits<T>::digits10);
    s << value;
    return s.str();
}


这将表现为数字类型所需的行为。请注意,我使用digits10而不是max_digits10来支持漂亮的十进制表示形式,而不是更多的数字并以..0000001结尾

同样,恕我直言,值得添加的是,[v][s][n]printf()与格式字符串“%.15g”(而不是'f')一起也将修剪尾随的零(将无法使用更多的数字,因为它们不能用64位表示,导致类似尾随的“ 1”,例如3.12->“ 3.1200000000000001”)

还是很奇怪:

也许有人可以告诉我,为什么将C ++-11硬代码引入的std::to_string(double)引入vsnprintf(..., "%f", ...),而不是vsnprintf("%.15g")这样的东西,而这会导致更精确的表示而不影响C代码?

最佳答案

您可以将字符串流(sstring)与流操纵器一起使用,请参见以下示例:

  std::stringstream ss1;
  std::stringstream ss2;
  ss1.precision(15);
  ss1 << 3.14;
  std::cout << ss1.str()<<' '<<("3.14" == ss1.str())<<std::endl;
  ss2.precision(15);
  ss2 << 3.1415926536;
  std::cout << ss2.str()<<' '<<("3.1415926536" == ss2.str())<<std::endl;


或者您可以使用升压格式。这是a link

  std::cout<<format("%.2f") % 3.14 <<std::endl;
  std::cout<<format("%.10f") % 3.1415926536 <<std::endl;

关于c++ - 带有动态精度的double到std::string(无尾随零),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35724411/

10-09 22:44