By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,660 Members | 1,945 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,660 IT Pros & Developers. It's quick & easy.

Problem with streams and 1.#INF

P: n/a
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::ofstream 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
Jul 22 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a

"Gustav Lead" <gl*************@spamgourmet.com> wrote in message
news:Xn**********************************@216.40.2 8.76...
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::ofstream 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
Jul 22 '05 #2

P: n/a
"Mike Wahler" <mk******@mkwahler.net> wrote in
news:xT***************@newsread1.news.pas.earthlin k.net:

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
Jul 22 '05 #3

P: n/a

"Gustav Lead" <gl*************@spamgourmet.com> wrote in message
news:Xn**********************************@216.40.2 8.76...
"Mike Wahler" <mk******@mkwahler.net> wrote in
news:xT***************@newsread1.news.pas.earthlin k.net:

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....


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
Jul 22 '05 #4

P: n/a
"Jeff Flinn" <NO****@nowhere.com> wrote in news:cc1h9n$kqb$1
@bluegill.adi.com:

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
Jul 22 '05 #5

P: n/a
From gmane.comp.lib.boost.devel
"Gustav Lead" <gl*************@spamgourmet.com> wrote in message
news:Xn**********************************@216.40.2 8.70...
"Jeff Flinn" <NO****@nowhere.com> wrote in news:cc1h9n$kqb$1
@bluegill.adi.com:

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.
If you want to store a special 'token' to indicate 'infinity', you'll
need to specifically parse for it.

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
Jul 22 '05 #6

P: n/a
"Jeff Flinn" <NO****@nowhere.com> wrote in message
news:cc**********@bluegill.adi.com...
If you want to store a special 'token' to indicate 'infinity', you'll
need to specifically parse for it.
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.


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
Jul 22 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.