Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

float128

#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/type_index.hpp>
#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.precision(std::numeric_limits<float128>::max_digits10);
std::cout << "pi = " << pi << std::endl; //pi = 3.14159265358979323846264338327950280

Values for std::numeric_limits<float128> are:

GCC 14.1.0

Type name: boost::multiprecision::float128
Full name: boost::multiprecision::number<boost::multiprecision::backends::float128_backend, (boost::multiprecision::expression_template_option)0>

std::is_fundamental<> = false
boost::multiprecision::detail::is_signed<> = false
boost::multiprecision::detail::is_unsigned<> = false
boost::multiprecision::detail::is_integral<> = false
boost::multiprecision::detail::is_arithmetic<> = false
std::is_const<> = false
std::is_trivial<> = false
std::is_trivially_copyable<> = true
std::is_standard_layout<> = true
std::is_pod<> = false
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.3621031431120935062626778173217526e-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<>::max_digits10 = 36
std::numeric_limits<>::has_denorm = 1
std::numeric_limits<>::denorm_min() = 6.47517511943802511092443895822764655e-4966
std::numeric_limits<>::has_denorm_loss = true
std::numeric_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.


PrevUpHomeNext