Boost logo

Boost :

Subject: Re: [boost] [serialization] round-trip serialization of float
From: Robert Ramey (ramey_at_[hidden])
Date: 2013-01-14 12:26:08


John Salmon wrote:
> On Fri, Jan 11, 2013 at 3:45 PM, Robert Ramey <ramey_at_[hidden]> wrote:
>
>> Adam Lerer wrote:
>>>>> a) not every binary floating number has en exact representation
>>>>> when rendered as decimal.
>>> True, but if max_digits10 digits is used, you can at least guarantee
>>> that the binary representation will deserialize as the same float.
>>> This is very helpful for common use cases of the serialization
>>> library
>>>
>>> I understand that float serialization cannot be guaranteed to work
>>> correctly in all cases. That said, the precision used for float
>>> serialization is a choice, and some choices are better than others.
>>> It seems to me that the choice of max_digits10 (or even better,
>>> Paul's alternative formula to work around the VS bug) is superior to
>>> digits10+2.
>>>
>>> It might also be helpful to note that lexical_cast uses exactly the
>>> formula that Paul recommends. In lcast_precision.hpp:
>>>
>>> BOOST_STATIC_CONSTANT(unsigned long, precision_bin =
>>> 2UL + limits::digits * 30103UL / 100000UL
>>> );
>>>
>>
>> Feel free to add a trac item for this
>>
>> Robert Ramey
>>
>>
>>
> FWIW, here's a patch that calls boost::detail::lcast_get_precision
> instead
> of digits10+2. It appears that the lexical_cast authors have thought
> through several portability/compatibility issues. Serialization
> might as well benefit from their work.
>
> The patch also has an overload of save(long double) which follows the
> same pattern as save(float) and save(double).
>
> John Salmon
>
>
> diff -Naur boost_1_52_0.orig/boost/archive/basic_text_oprimitive.hpp
> boost_1_52_0/boost/archive/basic_text_oprimitive.hpp
> --- boost_1_52_0.orig/boost/archive/basic_text_oprimitive.hpp
> 2011-01-19 12:33:55.000000000 -0500
> +++ boost_1_52_0/boost/archive/basic_text_oprimitive.hpp 2013-01-14
> 10:21:26.000000000 -0500
> @@ -33,6 +33,7 @@
> #include <boost/config.hpp>
> #include <boost/static_assert.hpp>
> #include <boost/detail/workaround.hpp>
> +#include <boost/detail/lcast_precision.hpp>
> #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
> #include <boost/archive/dinkumware.hpp>
> #endif
> @@ -130,7 +131,7 @@
> boost::serialization::throw_exception(
>
> archive_exception(archive_exception::output_stream_error)
> ); - os <<
> std::setprecision(std::numeric_limits<float>::digits10 + 2); +
> os << std::setprecision(boost::detail::lcast_get_precision<float>());
> os << t;
> }
> void save(const double t)
> @@ -140,7 +141,17 @@
> boost::serialization::throw_exception(
>
> archive_exception(archive_exception::output_stream_error)
> ); - os <<
> std::setprecision(std::numeric_limits<double>::digits10 + 2); +
> os << std::setprecision(boost::detail::lcast_get_precision<double>());
> + os << t;
> + }
> + void save(const long double t)
> + {
> + // must be a user mistake - can't serialize un-initialized
> data + if(os.fail())
> + boost::serialization::throw_exception(
> +
> archive_exception(archive_exception::output_stream_error) +
> ); + os <<
> std::setprecision(boost::detail::lcast_get_precision<long double>());
> os << t;
> }
> BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost

How about adding this as a comment/alternative/comparison to
https://svn.boost.org/trac/boost/ticket/7886

Robert Ramey


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk