c++ - double to std::string with dynamic precisicion (without trailing zeros)

标签 c++ string double

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

return std::to_string(double_value);

但这只返回 7 位数字,因为在内部 to_string() 只是使用 std::vsnprintf%f 格式说明符(另见here ).

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

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

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 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;

或者你可以使用 boost 格式。这是 a link !

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

关于c++ - double to std::string with dynamic precisicion (without trailing zeros),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35724411/

相关文章:

java - 字符串替换用 $ 符号抛出错误

JAVA:如何将 String 变量转换为 Double 变量?

Java 6 - 创建并检测第一个高于 Float.MAX_VALUE 的 Double 值

C# 操作溢出尝试将有效值分配给 double

c++ - 如何从写入文件的 UTF-8 编码 URDU 字符串中获取单个字符?

c++ - 如何修复 QHBoxLayout 项目大小并向 QHBoxLayout 中的每个项目添加下拉列表

c++ - 如何将 C 函数调用转换为 C++ 兼容语法?

c++ - std::pow 不返回预期的 int 值

c - C 和 strcpy 中的字符串指针数组

C文本游戏段错误及调试