Thread: streams of double and precision

1. streams of double and precision

Hi,

I have a peculiar problem when converting strings of numbers to double.

I open files that contain numbers in lines, such as:
Code:
`5.6 0 0.205867 1.0809 7.22644 0.373206 -5.84675e-317 1.99995 0.00433641 1.45331e-45`
I want to insert these numbers as double values in a vector of doubles.
My problem is with very small values, lower than 1e-310.

If I use this:
Code:
```vector<double> vals;
double x;
while (stream >> x) {
vals.push_back(x);
}```
then the vector vals is truncated and contains: 5.6 0 0.205867 1.0809 7.22644 0.373206
-5.84675e-317 is not only eliminated but the while loop ends.

I get the same issue using STL algorithms:

Code:
`copy(istream_iterator<double>(stream), istream_iterator<double>(), back_inserter(linevals) );`
However, this method works:
Code:
```vector<double> vals;
double x;
string st;
while (stream >> st) {
x = atof(st.c_str());
vals.push_back(x);
}```
How come atof is able to convert very small values, but not the other methods?

2. What compiler you are using?
I tried the following code in VS2005
Code:
```#include <vector>
#include <sstream>

int main()
{

std::stringstream stream("5.6 0 0.205867 1.0809 7.22644 0.373206 -5.84675e-317 1.99995 0.00433641 1.45331e-45");
std::vector<double> vals;
double x;
while (stream >> x)
{
vals.push_back(x);
}
return 0;
}```
And it finished parsing the string without problems
In debugger however I see for the value in question the following representation
-5.846749631800e-317#DEN

I do not know what does it mean

3. I think DEN means "denormalised" number: floating-point numbers follow a standard that changes their representation when they are close to 0.

I use gcc/g++ 4.2.2 on Unix (IBM AIX). I have not tried under Linux though.
I am going to try the code you show, thanks.

4. Right, so a E-317 number is "invalid" according to your current "read double from stream" implementation. You would have to differentiate that from other errors in input. Not sure what the best choice for this would be - the problem comes when trying to tell the difference between a malformed number and one that is out of range. E.g. 3.12B is a malformed number, whilst 1.3E-317 is a out of range number. Not sure how you would go about doing that.

Of course, you could read the number as a string and call strtod() to get it as a double, then check if ALL of the string was accepted by strtod().

--
Mats

5. Thanks for the suggestions. I tried the code on Linux (same g++ version) and there is no problem. It seems to be a specific issue with denormalized numbers on AIX platform. I reported the observation to the GCC bugzilla, I'll see if this is confirmed.