[Boost-bugs] [Boost C++ Libraries] #7886: Use 9 decimal digits for text serialization of float

Subject: [Boost-bugs] [Boost C++ Libraries] #7886: Use 9 decimal digits for text serialization of float
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-01-11 21:59:11


#7886: Use 9 decimal digits for text serialization of float
-----------------------------------------------+----------------------------
 Reporter: Adam Lerer <adam.lerer@…> | Owner: ramey
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: serialization
  Version: Boost 1.52.0 | Severity: Problem
 Keywords: |
-----------------------------------------------+----------------------------
 The boost serialization of float doesn't appear to use enough digits to
 guarantee that deserialization of a serialized float will produce the same
 value. The relevant code is in boost/archive/basic_text_oprimitive.hpp:

 {{{
 void save(const float t)
 {
     os << std::setprecision(std::numeric_limits<float>::digits10 + 2);
     ...
 }
 }}}


 std::numeric_limits<float>::digits10+2=8, but float actually requires
 numeric_limits<float>::max_digits10=9 decimal digits to guarantee unique
 representation.

 In order to work around a bug in VS's max_digits10, it might be better to
 use
 numeric_limits<T>::digits * 3010 / 10000. See
 http://boost.2283326.n4.nabble.com/serialization-Serialisation-
 deserialisation-of-floating-point-values-td2604169i20.html for details.

 On the boost mailing list, it was correctly pointed out that serializing
 floating-point to text cannot always be guaranteed to deserialize to the
 same value (e.g. across architectures), but for the common case, 9 digits
 is what is required to guarantee correct roundtrip serialization. Also,
 other libraries like boost::lexical_cast use 9 digits.

 ----
 The code below (with boost/1.52) demonstrates the problem:

 {{{
 #include <sstream>
 #include "boost/archive/text_iarchive.hpp"
 #include "boost/archive/text_oarchive.hpp"
 #include <iostream>

 int main(int argc, char **argv){
 float oldf = -1.20786635e-05;
 std::ostringstream os;
 boost::archive::text_oarchive oa(os);
 oa & BOOST_SERIALIZATION_NVP(oldf);

 float newf;
 std::istringstream is(os.str());
 boost::archive::text_iarchive ia(is);
 ia & BOOST_SERIALIZATION_NVP(newf);
 printf("before serialization: %.12g\nafter serialization: %.12g\n", oldf,
 newf);
 }

 ///Output:
 ///before serialization: -1.20786635307e-05
 ///after serialization: -1.20786644402e-05
 }}}

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/7886>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:11 UTC