The answer is based on the assumption that the OP uses MSVC
atof really better to read floating point values โโthan istream .
See this example:
#include <iostream> #include <sstream> #include <iomanip> #include <cstdlib> int main() { const char *val = "73.31"; std::stringstream ss; ss << val; float floatVal = 0.0f; ss >> floatVal; std::cout << "istream>>(float&) :" << std::setw(18) << std::setprecision(15) << floatVal << std::endl; double doubleVal = atof(val); std::cout << "double atof(const char*) :" << std::setw(18) << std::setprecision(15) << doubleVal << std::endl; floatVal = doubleVal; std::cout << "(float)double atof(const char*) :" << std::setw(18) << std::setprecision(15) << floatVal << std::endl; doubleVal = floatVal; std::cout << "(double)(float)double atof(const char*) :" << std::setw(18) << std::setprecision(15) << floatVal << std::endl; }
Output:
istream>>(float&) : 73.3100051879883 double atof(const char*) : 73.31 (float)double atof(const char*) : 73.3099975585938 (double)(float)double atof(const char*) : 73.3099975585938
The compiler even warns about converting from double to float this:
warning C4244: '=': conversion from 'double' to 'float', possible loss of data
I also found this page: Conversions from floating point types
Update:
The value 73.3099975585938 seems to be the correct interpretation of the float value of double 73.31 .
Update: istream>>(double&) works correctly:
#include <iostream> #include <sstream> #include <iomanip> #include <cstdlib> int main() { const char *val = "73.31"; std::stringstream ss; ss << val; double doubleVal = 0.0f; ss >> doubleVal; std::cout << "istream>>(double&) :" << std::setw(18) << std::setprecision(15) << doubleVal << std::endl; }
Output:
istream>>(double&) : 73.31
For arithmetic types istream::operator>> num_get::get . num_get::get should use something like scanf("%g") for float source
BUT:
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <iomanip> #include <cstdlib> int main() { std::string s = "73.31"; float f = 0.f; sscanf(s.c_str(), "%g", &f); std::cout << std::setw(18) << std::setprecision(15) << f << std::endl; }
Output:
73.3099975585938
For me it seems like a bug in Microsoft num_get
source share