double to std :: string with dynamic precisicion(不带尾随零)

时间:2016-03-01 13:37:04

标签: c++ string double

我想将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()与格式字符串&#34;%。15 g &#34;相加是值得的。 (而不是&#39; f&#39;)也会修剪尾随的零(因为它们无法用64位表示,因此无法用更多的数字表示,这会导致像尾随的那样#1;&#39; 1&#39; ;例如3.12 - &gt;&#34; 3.1200000000000001&#34;)

仍然很奇怪

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

1 个答案:

答案 0 :(得分:2)

您可以将字符串流(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;