[serialization] infinite floating point values

I just replaced the binary archives by text archives in an app,
to make sure that the archives will be portable between 32 and 64 bit
platforms.
But when I use text archives, the app crashes.
The problem is:
Text archives do not handle infinite values of type float and double.
--- Example ----------------------------------------------------------
#include <iostream>
#include <limits>
#include <sstream>
#include

This was the subject of some discussion. Its not really an issue with the serialization library itself as it is for stream i/o in general. After looking into this, it became apparent that that a) there is no agreed upon set of NaN types for all compilers. b) there is no general way to create a specific type of NaN c) other reasons I prefer not to go into here. But the good news is that its pretty easy to address for anyone who needs this functionality. Solution: a) create your own numput facets for input and output text streams. ideally there would be a couple of these facets. i) numput_strick - traps whenever a NaN is saved. This would support the view that no NaN's are expected in the output/input and would trap attempts to use them in this context. ii)numput_flakey - translates NaNs to/from some portable indicator and attempts to recreate the same type of NaN from the indicator. Usage: a) create a stream you're interested in - from fstream or whatever. b) pick the numput facet which implements the desired behavior and attach it to the stream c) pass the stream object to the text_archive upon opening. This approach would have a couple of advantages. a) it lets different users use thier own preferred way of handling this. b) it is useful beyond the serialization library. c) it leverages on known patterns and practices of the standard stream i/o d) its not that hard to do. e) it doesn't require messing with the serialization library. Although the topic incited a lot of interest - but not enough for anyone to actually to do the work to make such stream facets. Robert Ramey Johan Råde wrote:
I just replaced the binary archives by text archives in an app, to make sure that the archives will be portable between 32 and 64 bit platforms. But when I use text archives, the app crashes. The problem is:
Text archives do not handle infinite values of type float and double.
--- Example ----------------------------------------------------------
#include <iostream> #include <limits> #include <sstream> #include
#include #include int main() { std::stringstream ss;
{ boost::archive::text_oarchive oa(ss); double inf1 = std::numeric_limits<double>::infinity(); std::cout << boost::format("Save: %1%\n") % inf1; oa << inf1; }
{ boost::archive::text_iarchive ia(ss); double inf2; ia >> inf2; std::cout << boost::format("Load: %1%\n") % inf2; } }
--- Output ----------------------------------------------------------
Save: 1.#INF Load: 1
---------------------------------------------------------------------
There are two infinite values of type double, std::numeric_limits<double>::infinity() and -std::numeric_limits<double>::infinity(). These could be represented as "inf" and "-inf" in the archive.
I would be very useful for me if this functionality were added to the serialization library. (Otherwise I will have to do a lot of code rewriting, or stick binary archives.)
One could also consider handling nan (not a number), but that is maybe a lower priority.
--Johan Råde
rade@maths.lth.se

I agree. This has nothing to with the serialization lib. I will use the solution that you suggest. Thanks for the help. --Johan Råde Robert Ramey wrote:
This was the subject of some discussion. Its not really an issue with the serialization library itself as it is for stream i/o in general. After looking into this, it became apparent that that
a) there is no agreed upon set of NaN types for all compilers. b) there is no general way to create a specific type of NaN c) other reasons I prefer not to go into here.
But the good news is that its pretty easy to address for anyone who needs this functionality.
Solution:
a) create your own numput facets for input and output text streams. ideally there would be a couple of these facets. i) numput_strick - traps whenever a NaN is saved. This would support the view that no NaN's are expected in the output/input and would trap attempts to use them in this context. ii)numput_flakey - translates NaNs to/from some portable indicator and attempts to recreate the same type of NaN from the indicator.
Usage: a) create a stream you're interested in - from fstream or whatever. b) pick the numput facet which implements the desired behavior and attach it to the stream c) pass the stream object to the text_archive upon opening.
This approach would have a couple of advantages.
a) it lets different users use thier own preferred way of handling this. b) it is useful beyond the serialization library. c) it leverages on known patterns and practices of the standard stream i/o d) its not that hard to do. e) it doesn't require messing with the serialization library.
Although the topic incited a lot of interest - but not enough for anyone to actually to do the work to make such stream facets.
Robert Ramey
Johan Råde wrote:
I just replaced the binary archives by text archives in an app, to make sure that the archives will be portable between 32 and 64 bit platforms. But when I use text archives, the app crashes. The problem is:
Text archives do not handle infinite values of type float and double.
--- Example ----------------------------------------------------------
#include <iostream> #include <limits> #include <sstream> #include
#include #include int main() { std::stringstream ss;
{ boost::archive::text_oarchive oa(ss); double inf1 = std::numeric_limits<double>::infinity(); std::cout << boost::format("Save: %1%\n") % inf1; oa << inf1; }
{ boost::archive::text_iarchive ia(ss); double inf2; ia >> inf2; std::cout << boost::format("Load: %1%\n") % inf2; } }
--- Output ----------------------------------------------------------
Save: 1.#INF Load: 1
---------------------------------------------------------------------
There are two infinite values of type double, std::numeric_limits<double>::infinity() and -std::numeric_limits<double>::infinity(). These could be represented as "inf" and "-inf" in the archive.
I would be very useful for me if this functionality were added to the serialization library. (Otherwise I will have to do a lot of code rewriting, or stick binary archives.)
One could also consider handling nan (not a number), but that is maybe a lower priority.
--Johan Råde
rade@maths.lth.se
------------------------------------------------------------------------
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Should you decide to make the described num_put/get facets you might consider investing a little more effort to: a) make them templated on the char/wchar_t type. b) include a boost like document - you can use the utf-8 codecvt facet as a model. c) included a test or two. d) Upload the whole package to the vault. If you're a glutton for punishment, you can request a mini-review and maybe get it accepted into Boost. I would be personally grateful to anyone who undertakes this as it would resolve, an issue which comes up repeatedly. Of course nothing is easy as it first appears. There is the quesion of how such facets might interact with other locale dependent facets. Also I'm not sure that stringstream handles these facets in the same way as other ones do. Hopefully, all these questions would be addressed with a little research..... And you need to do it anyway for your own application. This is just about as close as you're ever going to get to being famous for nothing. Good Luck Robert Ramey Johan Råde wrote:
I agree. This has nothing to with the serialization lib. I will use the solution that you suggest. Thanks for the help.
--Johan Råde
cgi/boost-users

I will put together a facet that solves my problem on the platforms that I'm targeting. I don't know if it's possible to put together a general solution that works for all projects with all compilers and all processors. I was very surprised when you told me that the problem was with the streams. It is strange that std::stringstream s; double x = std::numeric_limits<double>::infinity(); double y; ss << x; ss >> y; assert(x == y); does not work (at least not with VC++ 7.1). --Johan Råde Robert Ramey wrote:
Should you decide to make the described num_put/get facets you might consider investing a little more effort to:
a) make them templated on the char/wchar_t type. b) include a boost like document - you can use the utf-8 codecvt facet as a model. c) included a test or two. d) Upload the whole package to the vault.
If you're a glutton for punishment, you can request a mini-review and maybe get it accepted into Boost.
I would be personally grateful to anyone who undertakes this as it would resolve, an issue which comes up repeatedly.
Of course nothing is easy as it first appears. There is the quesion of how such facets might interact with other locale dependent facets. Also I'm not sure that stringstream handles these facets in the same way as other ones do. Hopefully, all these questions would be addressed with a little research..... And you need to do it anyway for your own application. This is just about as close as you're ever going to get to being famous for nothing.
Good Luck
Robert Ramey
Johan Råde wrote:
I agree. This has nothing to with the serialization lib. I will use the solution that you suggest. Thanks for the help.
--Johan Råde
cgi/boost-users
------------------------------------------------------------------------
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Johan Råde
-
Robert Ramey