...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
#include <boost/multiprecision/float128.hpp>
namespace boost{ namespace multiprecision{ class float128_backend; typedef number<float128_backend, et_off> float128; }} // namespaces
The float128
number type
is a very thin wrapper around GCC's float128
or Intel's _Quad
data types
and provides an real-number type that is a drop-in replacement for the
native C++ floating-point types, but with a 113 bit mantissa, and compatible
with FORTRAN's 128-bit QUAD real.
All the usual standard library and numeric_limits
support are available, performance should be equivalent to the underlying
native types: for example the LINPACK benchmarks for GCC's float128
and boost::multiprecision::float128
both achieved 5.6 MFLOPS[3].
As well as the usual conversions from arithmetic and string types, instances
of float128
are copy constructible
and assignable from GCC's float128
and Intel's _Quad
data
types.
It's also possible to access the underlying float128
or _Quad
type via the
data()
member function of float128_backend
.
Things you should know when using this type:
float128
s
have the value zero.
number
on this backend
move aware.
constexpr
aware - basic constexpr arithmetic is supported from C++14 and onwards,
comparisons, plus the functions fabs
,
abs
, fpclassify
, isnormal
,
isfinite
, isinf
and isnan
are also supported if either the compiler implements C++20's std::is_constant_evaluated()
,
or if the compiler is GCC.
_Quad
as the underlying type: this is a current limitation of our code. Round
tripping when using float128
as the underlying type is possible (both for GCC and Intel).
std::runtime_error
being thrown if the string can not be interpreted as a valid floating-point
number.
float128
can be
used as a literal type (constexpr support).
float128
can be
used for full constexpr
arithmetic from C++14 and later with GCC. The functions abs
, fabs
,
fpclassify
, isnan
, isinf
,
isfinite
and isnormal
are also constexpr
,
but the transcendental functions are not.
float128
if it's available and _Quad
if not. You can override the default by defining either BOOST_MP_USE_FLOAT128
or BOOST_MP_USE_QUAD
.
_Quad
type, the code must be compiled with the compiler option -Qoption,cpp,--extended_float_type
.
gcc
,
you need to use the flag --std=gnu++11/14/17
,
as the suffix 'Q' is a GNU extension. Compilation fails with the flag
--std=c++11/14/17
unless you also use -fext-numeric-literals
.
#include <boost/multiprecision/float128.hpp> #include <boost/math/special_functions/gamma.hpp> #include <iostream> int main() { using namespace boost::multiprecision; // Operations at 128-bit precision and full numeric_limits support: float128 b = 2; // There are 113-bits of precision: std::cout << std::numeric_limits<float128>::digits << std::endl; // Or 34 decimal places: std::cout << std::numeric_limits<float128>::digits10 << std::endl; // We can use any C++ std lib function, lets print all the digits as well: std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10) << log(b) << std::endl; // print log(2) = 0.693147180559945309417232121458176575 // We can also use any function from Boost.Math: std::cout << boost::math::tgamma(b) << std::endl; // And since we have an extended exponent range we can generate some really large // numbers here (4.02387260077093773543702433923004111e+2564): std::cout << boost::math::tgamma(float128(1000)) << std::endl; // // We can declare constants using GCC or Intel's native types, and the Q suffix, // these can be declared constexpr if required: constexpr float128 pi = 3.1415926535897932384626433832795028841971693993751058Q; return 0; }