Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) ToDouble

 

ToDouble is a conversion code snippet to convert a std::string to double.

 

ToDouble can be implemented in multiple equivalent ways (incomplete list):

  1. ToDouble using std::atof
  2. ToDouble using std::strtod
  3. ToDouble using std::istringstream

 

To conversion a std::string to any data type one can use LexicalCast and boost::lexical_cast.

 

 

 

 

 

ToDouble using std::atof

 

#include <cstdlib>
#include <string>

//From http://www.richelbilderbeek.nl/CppToDouble.htm
double ToDouble(const std::string& s)
{
  return std::atof(s.c_str());
}

 

 

 

 

 

ToDouble using std::istringstream

 

The implementation below is similar to the C++ FAQ Lite's convertToDouble code snippet.

 

#include <sstream>
#include <stdexcept>
#include <string>

//From http://www.richelbilderbeek.nl/CppToDouble.htm
double ToDouble(std::string const& s)
{
  std::istringstream i(s);
  double x;
  if (!(i >> x))
  {
    throw std::logic_error("std::string cannot be converted to double");
  }
  return x;
}

 

 

 

 

 

ToDouble using std::strtod

 

#include <cstdlib>
#include <string>

//From http://www.richelbilderbeek.nl/CppToDouble.htm
double ToDouble(const std::string& s)
{
  return std::strtod(s.c_str(),0);
}

 

 

 

 

 

ToDouble tests

 

In the code below, all ToDouble flavors are compared and found out equivalent.

 

#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>

//From http://www.richelbilderbeek.nl/CppToDouble.htm
double ToDoubleUsingAtof(const std::string& s)
{
  return std::atof(s.c_str());
}

//From http://www.richelbilderbeek.nl/CppToDouble.htm
double ToDoubleUsingStrtod(const std::string& s)
{
  return std::strtod(s.c_str(),0);
}

//From http://www.richelbilderbeek.nl/CppToDouble.htm
double ToDoubleUsingStream(std::string const& s)
{
  std::istringstream i(s);
  double x;
  if (!(i >> x))
  {
    throw std::logic_error("std::string cannot be converted to double");
  }
  return x;
}

const char GetRandomDigit()
{
  switch (std::rand() % 10)
  {
    case 0: return '0';
    case 1: return '1';
    case 2: return '2';
    case 3: return '3';
    case 4: return '4';
    case 5: return '5';
    case 6: return '6';
    case 7: return '7';
    case 8: return '8';
    case 9: return '9';
  }
}

const std::string GetRandomDouble()
{
  const std::string sign = ((std::rand() >> 4) % 2 ? "+" : "-");

  std::string s1;
  s1.resize(1 + (std::rand() % 3));
  std::generate(s1.begin(),s1.end(),GetRandomDigit);

  std::string s2;
  s2.resize(1 + (std::rand() % 5));
  std::generate(s2.begin(),s2.end(),GetRandomDigit);

  const std::string s = sign + s1 + "." + s2;
  return s;
}

int main()
{
  for (int i=0; i!=20; ++i)
  {
    const std::string s = GetRandomDouble();
    std::cout << s << ":\t" << ToDoubleUsingAtof(s) << '\n';
    assert(ToDoubleUsingAtof(s)==ToDoubleUsingStrtod(s));
    assert(ToDoubleUsingAtof(s)==ToDoubleUsingStream(s));
  }

}

 

Screen output:

 

+67.3: 67.3
+29.27: 29.27
+36.6: 36.6
-18.920: -18.92
+75.22897: 75.229
+12.31947: 12.3195
+503.10: 503.1
-2.6: -2.6
-5.76569: -5.76569
+452.4: 452.4
-430.868: -430.868
+3.49: 3.49
+6.9266: 6.9266
-504.7172: -504.717
+2.10: 2.1
+59.90917: 59.9092
-159.767: -159.767
+5.39: 5.39
+12.39088: 12.3909
+96.8561: 96.8561

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict