Double to string in C++

Double to string in C++ 

Sat October 29, 2022 11:18 PM

In C++  , there are multiple functions which are useful in formatted I/O. to_string(), std::ostringstreamboost::lexical_cast(c++17) and sprintf functions are in the list. It returns a string representation of value.

This article will discuss different alternatives to convert double datatype in to string and its comparison on each other .

Commonly in C++ code,  the library function std::to_string is to convert any numeric data type in to string  type. It works on fundamental numeric types and available since C++11 and is very useful in formatted I/O.  It was designed to produce the same results that sprintf would.
 Example:

Float f = 3.0

std::string str = std::to_string(f)

With floating point types std::to_string may yield unexpected results as the number of significant digits in the returned string can be zero and The return value may differ significantly from what std::cout prints by default fir double values.

 Example:

In the below code, we declared 4 variables of double type ranging from a very small to a very large number to see the various kinds of outputs using  each function.  

 for (const double f : {23.43, 1e-9, 1e40 ,1e-40})

        std::cout << "std::cout: " << f << '\n'

                  << "to_string: " << std::to_string(f) << "\n\n";
Output:

std::cout: 23.43

to_string: 23.430000

std::cout: 1e-09

to_string: 0.000000

std:cout: 1e+40

to_string: 10000000000000000303786028427003666890752.000000

std::cout: 1e-40

to_string: 0.000000

Here, The scale values for double values are different from what was expected by the value provided.  std::to_string() prints every digit, and six decimal places. It has a default precision of six digits which cannot be changed.
A double can also be converted into a string in C++ using stringstream in different ways according to our requirements. Output of the similar code using stringstream is as follows:

Ostringstream ss;

 for (const double f : {23.43, 1e-9, 1e40 ,1e-40})

        std::cout << "std::cout: " << f << '\n'

                  << "to_string: " <<ss.str() << "\n\n";

std::cout: 23.43

to string: 23.43

std::cout:: 1e-09

to string: 1e-09

std::cout:1e+40

to string: 1e+40

std::cout: 1e-40

to string: 1e-40

For large numbers, ostringstream automatically converts it to scientific notation. We can customize to get the output as fixed-point notation  than scientific notation. It  also has a default precision of six digits and can be customized by setting the precision.

Boost.LexicalCast which is defined in the Library “boost/lexical_cast.hpp” also provides a cast operator, boost::lexical_cast, that can also  convert numbers from strings to numeric types like int or double and vice versa. boost::lexical_cast is an alternative to functions like std::stoi(), std::stod() , and std::to_string(), which were added to the standard library in C++11. Now let see the Implementation of this function in a program. 

 for (const double f : {23.43, 1e-9, 1e-40})

        std::cout << "std::cout: " << f << '\n'

                  << "lexical_cast: " << lexical_cast<std::string>(f) << "\n\n";

std::cout: 23.43

lexical_cast:: 23.43

std::cout: 1e-09

lexical_cast:: 1e-09

std::cout: 1e40

lexical_cast:: 1e40

std::cout: 1e-40

lexical_cast:: 1e-40

As you can see, the boost version uses exponential notation (1e-40) whereas std::to_string prints digit, and six decimal places and ostringstream can have both fixed and scientific  notation as well as to handle customized precision values. I would say ,

  • Always use std::to_string to convert any single value to std::string, if precison is not an issue.
  • In case of double, use std::string. If you need precision, use std::ostringstream.
  • Prefer boost::lexical_cast if you have boost in your project