...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Construction of multiprecision types from built-in floating-point types
can lead to potentially unexpected, yet correct, results. Consider, for
instance constructing an instance of cpp_dec_float_50
from the literal built-in floating-point double
value 11.1.
#include <iomanip> #include <iostream> #include <limits> #include <boost/multiprecision/cpp_dec_float.hpp> int main() { using my_dec_100 = boost::multiprecision::cpp_dec_float_50; const my_dec_100 f11(11.1); // On a system with 64-bit double: // 11.09999999999999964472863211994990706443786621093750 std::cout << std::setprecision(std::numeric_limits<my_dec_100>::digits10) << std::fixed << f11 << std::endl; }
In this example, the system has a 64-bit built in double
representation. The variable f11
is initialized with the literal double
value 11.1. Recall that built-in floating-point representations are based
on successive binary fractional approximations. These are, in fact, very
close approximations. But they are approximations nonetheless, having
their built-in finite precision.
For this reason, the full multiple precision value of the double
approximation of 11.1 is given
by the large value shown above. Observations show us that the value is
reliable up to the approximate 15 decimal digit precision of built-in
64-bit double
on this system.
If the exact value of 11.1 is desired (within the wider precision of the multiprecision type), then construction from literal string or from a rational integral construction/division sequence should be used.
const my_dec_100 f11_str("11.1"); const my_dec_100 f11_n (my_dec_100(111) / 10);