Boost C++ Libraries 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 std::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 example:
#include <boost/multiprecision/float128.hpp>
#include <boost/math/special_functions/gamma.hpp>
#include <iostream>

int main()
   using namespace boost::multiprecision; // Potential to cause name collisions?
   // using boost::multiprecision::float128; // is safer.

The type float128 provides operations at 128-bit precision with Quadruple-precision floating-point format and have full std::numeric_limits support:

float128 b = 2;

There are 15 bits of (biased) binary exponent and 113-bits of significand precision

std::cout << std::numeric_limits<float128>::digits << std::endl;

or 33 decimal places:

std::cout << std::numeric_limits<float128>::digits10 << std::endl;

We can use any C++ std library function, so let's show all the at-most 36 potentially significant digits, and any trailing zeros, as well:

 std::cout.setf(std::ios_base::showpoint); // Include any trailing zeros.
std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10)
   << log(b) << std::endl; // Shows log(2) = 0.693147180559945309417232121458176575

We can also use any function from Boost.Math, for example, the 'true gamma' function tgamma:

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 literals with the Q suffix, and these can be declared constexpr if required:

// std::numeric_limits<float128>::max_digits10 = 36
constexpr float128 pi = 3.14159265358979323846264338327950288Q;
std::cout << "pi = " << pi << std::endl; //pi = 3.14159265358979323846264338327950280

Values for std::numeric_limits<float128> are:

GCC 8.1.0

Type name is float128_t:
Type is g
std::is_fundamental<> = true
std::is_signed<> = true
std::is_unsigned<> = false
std::is_integral<> = false
std::is_arithmetic<> = true
std::is_const<> = false
std::is_trivial<> = true
std::is_standard_layout<> = true
std::is_pod<> = true
std::numeric_limits::<>is_exact = false
std::numeric_limits::<>is bounded = true
std::numeric_limits::<>is_modulo = false
std::numeric_limits::<>is_iec559 = true
std::numeric_limits::<>traps = false
std::numeric_limits::<>tinyness_before = false
std::numeric_limits::<>max() = 1.18973149535723176508575932662800702e+4932
std::numeric_limits::<>min() = 3.36210314311209350626267781732175260e-4932
std::numeric_limits::<>lowest() = -1.18973149535723176508575932662800702e+4932
std::numeric_limits::<>min_exponent = -16381
std::numeric_limits::<>max_exponent = 16384
std::numeric_limits::<>epsilon() = 1.92592994438723585305597794258492732e-34
std::numeric_limits::<>radix = 2
std::numeric_limits::<>digits = 113
std::numeric_limits::<>digits10 = 33
std::numeric_limits::<>max_digits10 = 36
std::numeric_limits::<>has denorm = true
std::numeric_limits::<>denorm min = 6.47517511943802511092443895822764655e-4966
std::denorm_loss = false
limits::has_signaling_NaN == false
std::numeric_limits::<>quiet_NaN = nan
std::numeric_limits::<>infinity = inf

[3] On 64-bit Ubuntu 11.10, GCC-4.8.0, Intel Core 2 Duo T5800.