Boost logo

Boost Users :

From: Johan Råde (rade_at_[hidden])
Date: 2008-02-21 06:07:50

Pfligersdorffer, Christian wrote:
> Hello all,
> we use fp_utilities in our portable binary archive implementation to
> serialize floating point numbers. For doing so we found the functions
> fp_traits<T>_impl::get_bits() and set_bits() to be exactly what we need.
> In combination with Beman Dawes endian library we're able to transfer
> binary data between ppc-32 and x86-32 reliably. This might serve as a
> usecase since John Maddock pointed out serialization as a prominent
> application of the library.
> /**
> * save floating point types
> *
> * We simply rely on fp_traits to extract the bit pattern into an
> (unsigned)
> * integral type and store that into the stream.
> *
> * \todo treat nan values using fp_classify
> */
> template <typename T>
> BOOST_DEDUCED_TYPENAME boost::enable_if<boost::is_floating_point<T>
>> ::type
> save(const T & t, dummy<3> = 0)
> {
> using namespace boost::math::detail;
> BOOST_DEDUCED_TYPENAME fp_traits<T>::type::bits bits;
> fp_traits<T>::type::get_bits(t, bits);
> save(bits);
> }
> As you can see our code depends on functions that apparently are not
> part of the public interface and I wonder why. Perhaps I overlooked
> something? Those interested in the full code can find it in the boost
> vault.

Hi Christian,

You are using an undocumented internal implementation detail of the library
for a purpose for which it is not intended.

Be warned that the math::detail::fp_traits<T>::type::get_bits() function
is *not* guaranteed to give you all bits of the floating point number.
It will give you all bits if and only if there is an integer type
that has the same size as the floating point you are copying from.
It will not give you all bits for double if there is no uint64_t.
It will not give you all bits for long double if sizeof(long double) > 8 or there is no uint64_t.

The member fp_traits<T>::type::coverage will tell you whether all bits are copied.
This is a typedef for either math::detail::all_bits or math::detail::not_all_bits.

If the function does not copy all bits,
then it will copy the most significant bits.
So if you serialize and deserialize the way you describe,
and fp_traits<T>::type::coverage is math::detail::not_all_bits,
then your floating point numbers will be truncated.
This will introduce small rounding off errors.

Be careful,
Johan Råde

> To sum it up: We think the fp_utilities provide useful functionality and
> our tests indicate reliability that can be counted on. So thank you
> Johan Rade for this contribution!
> Best Regards,
> --
> Christian Pfligersdorffer
> Software Engineering

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at