Problem with streams and 1.#INF

G

Gustav Lead

Hi all,

I have trouble reading back floating point data from a file.

It appears as if the tokens for positive and negative infinity (1.#INF
and -1.#INF) that my implementation writes get misinterpreted (to 1.0
and -1.0) when I try to read them back in.

#include <fstream>
#include <limits>

void somefunction()
{

double d_infinity = std::numeric_limits<double>::infinity();
std::eek:fstream output;
output.open("file.txt");
output << d_infinity;
output.close();

double d_test1 = 0;
std::ifstream input;
input.open("file.txt");
input >> d_test1;
input.close();

}

The contents of "file.txt" is "1.#INF".
At the end of the function the value of d_test1 is 1.0 .
Trying to read in more data after that will fail, because the "#INF"
fragment remains in the stream.

Is this a problem of my STL implementation (I am using MSVC 7.1), or do
I have to make some change to my code to get this to work correctly?


Thanks in advance,
G L
 
M

Mike Wahler

Gustav Lead said:
Hi all,

I have trouble reading back floating point data from a file.

It appears as if the tokens for positive and negative infinity (1.#INF
and -1.#INF) that my implementation writes get misinterpreted (to 1.0
and -1.0) when I try to read them back in.

C++ doesn't define tokens for 'infinity'. The output you see
is what your implementation outputs when it detects 'infinity'.
#include <fstream>
#include <limits>

void somefunction()
{

double d_infinity = std::numeric_limits<double>::infinity();
std::eek:fstream output;
output.open("file.txt");
output << d_infinity;
output.close();

double d_test1 = 0;
std::ifstream input;
input.open("file.txt");
input >> d_test1;
input.close();

}

The contents of "file.txt" is "1.#INF".

In which case the extractor for type 'double' will parse the
characters '1' and '.', and then stop, since '#' is not a valid
character in a floating point number. Same as if you'd tried
to read e.g. 42X into an 'int' object. You'd get 42, with the
'X' remaining in the stream.
At the end of the function the value of d_test1 is 1.0 .

That's the entirety of the valid floating point characters
until the first invalid character.
Trying to read in more data after that will fail, because the "#INF"
fragment remains in the stream.

Trying to read more as numeric will fail, yes, because '#' is not
a valid numeric character.
Is this a problem of my STL implementation (I am using MSVC 7.1),

No, this is by design.
or do
I have to make some change to my code to get this to work correctly?

If you want to store a special 'token' to indicate 'infinity', you'll
need to specifically parse for it.

Typically numeric input is handled more robustly by reading a 'line'
as a string, and using conversion functions after the fact (e.g. 'strod()'
or an istringstream extractor). To check for your 'infinity' token,
just search the string for that first.

-Mike
 
G

Gustav Lead

Mike Wahler said:
No, this is by design.
If you want to store a special 'token' to indicate 'infinity', you'll
need to specifically parse for it.

Typically numeric input is handled more robustly by reading a 'line'
as a string, and using conversion functions after the fact (e.g.
'strod()' or an istringstream extractor). To check for your
'infinity' token, just search the string for that first.

-Mike

Thanks for your answer, Mike!

Unfortunatly this is not an option for me, because I am using a
serialization library (Boost::Serialization currently at
http://www.rrsd.com/boost/) and I have to rely on the STL stream library
operators to read back all of their repective data as they wrote it into
the stream and to properly restore the state of the object.

Perhaps I could alter the behavior of the "ostream& operator<<(ostream&,
double)" (and istream)?

I think overloading would be a redefintion and is out of the question
(or is it???) unless I make some kind of wrapper for doubles, but maybe
it is possible to do this with locales (or facets?) ?

Locales are really terra incognita for me, so I'd really like some
advice if this is a viable option at all, before I try to go down that
path.

Any other idea for a solution would of course be just as welcome....


Thanks,
GL
 
J

Jeff Flinn

Gustav Lead said:
Thanks for your answer, Mike!

Unfortunatly this is not an option for me, because I am using a
serialization library (Boost::Serialization currently at
http://www.rrsd.com/boost/) and I have to rely on the STL stream library
operators to read back all of their repective data as they wrote it into
the stream and to properly restore the state of the object.

Perhaps I could alter the behavior of the "ostream& operator<<(ostream&,
double)" (and istream)?

I think overloading would be a redefintion and is out of the question
(or is it???) unless I make some kind of wrapper for doubles, but maybe
it is possible to do this with locales (or facets?) ?

Locales are really terra incognita for me, so I'd really like some
advice if this is a viable option at all, before I try to go down that
path.

Any other idea for a solution would of course be just as welcome....

Have you informed Robert of this issue? You should post this on the boost
development mailing list. If you don't have access let me know, and I'll
pass it on.

Jeff F
 
G

Gustav Lead

Have you informed Robert of this issue? You should post this on the boost
development mailing list. If you don't have access let me know, and I'll
pass it on.

Jeff F

No, I haven't. I don't have access, but I will try to subscribe to it now.
However, this could take some time, so I'd be grateful if you could post it
there for me.

Thanks,
GL
 
J

Jeff Flinn

From gmane.comp.lib.boost.devel


Gustav Lead said:
No, I haven't. I don't have access, but I will try to subscribe to it now.
However, this could take some time, so I'd be grateful if you could post it
there for me.
Perhaps I could alter the behavior of the "ostream& operator<<(ostream&,
double)" (and istream)?
Any other idea for a solution would of course be just as welcome....


Problem - serialization of a float/double with an Infinite or Nan value
Fails with a text archive. This is due to the fact that the this archive
class depends upon implementation of stream I/o which apparently doesn't
consider these values for floats.

I would suggest making a small derivation from the standard text archive
which overrides the existing implementation of the load(float &) and
load(double &) with a slightly more elaborate one which can handle these
values. There is an example in the manual on how to do this. I'm no sure
whether or not this facility should be part of the standard text archive or
not.

Fast workaround - use the native binary archive which just saves/loads the
raw bits without trying to interpret them.

Robert Ramey




_______________________________________________
Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost
 
P

P.J. Plauger

Problem - serialization of a float/double with an Infinite or Nan value
Fails with a text archive. This is due to the fact that the this archive
class depends upon implementation of stream I/o which apparently doesn't
consider these values for floats.

I would suggest making a small derivation from the standard text archive
which overrides the existing implementation of the load(float &) and
load(double &) with a slightly more elaborate one which can handle these
values. There is an example in the manual on how to do this. I'm no sure
whether or not this facility should be part of the standard text archive or
not.

Fast workaround - use the native binary archive which just saves/loads the
raw bits without trying to interpret them.

Yet another approach is to use a library that can read back what it writes
for NaN and Inf. If you use our C library with our C++ library, you get
such behavior.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top