I'm working with a library that unfortunately uses boost::lexical_cast
to convert from a double
to a string
.
I need to be able to definitively mirror that behavior on my side, but I was hopping to do so without propagating boost
.
Could I be guaranteed identical behavior using to_string
, sprintf
, or some other function contained within the standard?
The boost code ends up here:
You're in luck since the precision is USUALLY compile-time constant (unless boost configures
BOOST_LCAST_NO_COMPILE_TIME_PRECISION
).Simplifying a bit and allowing for conforming, modern standard libraries:
Mimicking Boost Lexicalcast
Regression Tests
To compare the results and check the assumptions:
Live On Coliru
Prints
Note that
mimicked
andboost::lexical_cast<std::string>(double)
result in exactly the same output each time.So after a few hours of digging around in Boost templates here's what I've learned:
lexical_cast_do_cast<std::string, double>::lexical_cast_impl
std::sprintf
withinboost::detail::lexical_stream_limited_src<char, std::char_traits<char>, false>
boost::detail::lexical_stream_limited_src<char, std::char_traits<char>, true>::operator<<
will be used to insert thedouble
, passingbegin
, the pointer to an allocatedstd::string
's buffer, andval
, the inputdouble
, yields this call:std::sprintf(begin, "%.*g", static_cast<int>(boost::detail::lcast_get_precision<double>()), val)
boost::details::lcast_precision<double>::value
, which, will usestd::numeric_limits<double>
; if it'sis_specialized
isfalse
,is_exact
isfalse
,radix
is2
, anddigits
is greater than0
thenboost::details::lcast_precision<double>::value
will evaluate to:2UL + std::numeric_limits<double>::digits * 30103UL / 100000UL
Thus where
begin
is the allocatedstring
andval
is the input double,boost::lexical_cast<double>
yields a final result the equivalent of:This is obviously heavily implementation dependent. But on my system this will yield the exact equivalent.