Quote:
Be aware that using atof only "works" in this case because you are testing for a number which is a power of two or one less that a power of two. Generally double-precision floating point numbers do not have enough precision to guarantee correct results. Try testing for a range of +-2000000000 to see what I mean. Furthermore that "works" is in inverted commas for a reason. In the event that the input number exceeds the valid range for a double-precision floating point number the result is technically undefined, even though all my implementations actually return +/-infinity.
Hmmm, I executed this:
#include <string>#include <iostream>#include <sstream>using namespace std;typedef signed int Sint32;string temp;stringstream sstr;void checkint(Sint32 num) { sstr.clear(); sstr << num; temp.clear(); sstr >> temp; double integer = atof(temp.c_str()); if ( !( (integer <= (double) 2147483647.0) && (integer >= (double) -2147483648.0f)) ) { cout << "! Error ! Parsed integer " << num << " and got in result " << temp << " which appears to be outside range\n"; } if (num % 1000) cout << num << endl; }int main(){ for (Sint32 i = -7483648; i < 7483647; i += 10) checkint(i);}
No errors occured, also when I changed
for (Sint32 i = -7483648; i < 7483647; i += 10)
to
for (Sint32 i = -2000000000; i < 2000000000; i += 1000)
// btw, it produced 40 MB txt file :-)
Also, I've tried going over whole range -2147483648 to 2147483647 by 1... but after few minutes, when history of cache use skyrocketed to the point not seen even when playing Doom 3 on my old computer I had to kill it. But even then, the re were no errors in txt file.
------
Uhm, this works too:
void checkint(Sint32 num) { sstr.clear(); sstr << num; temp.clear(); sstr >> temp; double integer = atof(temp.c_str()); if ( !( (integer <= (double) 2147483647.0) && (integer >= (double) -2147483648.0f)) ) cout << "! Error ! Parsed integer " << num << " and got in result " << temp << " which appears to be outside range\n"; if (num != static_cast<Sint32> (integer)) cout << "! Error ! Parsed integer " << num << " and got in result " << static_cast<Sint32> (integer) << " which appears to be different!\n"; }int main(){ for (Sint32 i = -2147483648; i < 2147483647; ++i) checkint(i); }
However, I couldn't wait until it finishes, so after few minutes once again I had to kill it. But there were no errors reported...
Btw, when my MinGW sees -2147483648, it complains about "[Warning] this decimal constant is unsigned only in ISO C90 " :-?
Quote:
In general there is no reason to prefer atoi and atof over C++ streams except for the very limited case where you can guarantee the range of input and need to perform string to integer/floating point values frequently in a tight loop and a profiler has demonstrated the conversion to be a bottleneck
For me, there is one, little, not-very-important, albeit existing reason: need to include <sstream>, which may slightly increase produced lib. Ok ok, I know that's going to add max. only few kb. Anyway, I've already implemented atof, and I'm going to change it only if it will cause any errors,
Btw, now I've also remembered that atof will be called only for strings which have their size not bigger than 10 (or 11 if minust stands first). So in the extreme case I'll get 9999999999 - AFAIK atof should work fine with such things.