代码之家  ›  专栏  ›  技术社区  ›  frans

双精度到std::字符串,具有动态精度(不带尾随零)

  •  0
  • frans  · 技术社区  · 9 年前

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

    return std::to_string(double_value);
    

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

    我现在可以打电话了 标准::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++中,双精度无尾随零?

    解决方案:

    基于 2man s答案你可以写一个这样的泛型函数:

    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() 以及格式字符串“%.15 “(而不是‘f’)还将修剪尾随的零(不能使用更多的数字,因为它们不能用64位表示,这会导致尾随的‘1’,例如3.12->”3.1200000000000001")

    还是很奇怪 :

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

    1 回复  |  直到 8 年前
        1
  •  3
  •   2man    9 年前

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