Precise floating-point<->string conversion

后端 未结 5 497
误落风尘
误落风尘 2020-12-09 05:03

I am looking for a library function to convert floating point numbers to strings, and back again, in C++. The properties I want are that str2num(num2str(x)) == x and that nu

5条回答
  •  眼角桃花
    2020-12-09 05:51

    The reason for wanting these functions is to save floating point values to CSV files, and then read them correctly. In addition, I'd like the CSV files to contain simple numbers as far as possible so they can be consumed by humans.

    You cannot have conversion double → string → double and in the same time having the string human readable.

    You need to need to choose between an exact conversion and a human readable string. This is the definition of max_digits10 and digits10:

    • difference explained by stackoverflow
    • digits10
    • max_digits10

    Here is an implementation of num2str and str2num with two different contexts from_double (conversion double → string → double) and from_string (conversion string → double → string):

    #include 
    #include 
    #include 
    #include 
    
    namespace from_double
    {
      std::string num2str(double d)
      {
        std::stringstream ss;
        ss << std::setprecision(std::numeric_limits::max_digits10) << d;
        return ss.str();
      }
    
      double str2num(const std::string& s)
      {
        double d;
        std::stringstream ss(s);
        ss >> std::setprecision(std::numeric_limits::max_digits10) >> d;
        return d;
      }
    }
    
    namespace from_string
    {
      std::string num2str(double d)
      {
        std::stringstream ss;
        ss << std::setprecision(std::numeric_limits::digits10) << d;
        return ss.str();
      }
    
      double str2num(const std::string& s)
      {
        double d;
        std::stringstream ss(s);
        ss >> std::setprecision(std::numeric_limits::digits10) >> d;
        return d;
      }
    }
    
    int main()
    {
      double d = 1.34;
      if (from_double::str2num(from_double::num2str(d)) == d)
        std::cout << "Good for double -> string -> double" << std::endl;
      else
        std::cout << "Bad for double -> string -> double" << std::endl;
    
      std::string s = "1.34";
      if (from_string::num2str(from_string::str2num(s)) == s)
        std::cout << "Good for string -> double -> string" << std::endl;
      else
        std::cout << "Bad for string -> double -> string" << std::endl;
    
      return 0;
    }
    

提交回复
热议问题