Boost logo

Boost :

Subject: [boost] [serialization] round-trip serialization of float
From: Adam Lerer (adam.lerer_at_[hidden])
Date: 2013-01-09 17:26:02


The boost serialization of float doesn't appear to use enough digits to
guarantee that deserialization of a serialized value 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.

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

Note: There's some discussion of this topic in a slightly different context
here:
http://boost.2283326.n4.nabble.com/serialization-Serialisation-deserialisation-of-floating-point-values-td2604169i20.html


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