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

float128
PrevUpHomeNext

#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:

  • Default constructed float128s have the value zero.
  • This backend supports rvalue-references and is move-aware, making instantiations of number on this backend move aware.
  • This type is fully 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.
  • It is not possible to round-trip objects of this type to and from a string and get back exactly the same value when compiled with Intel's C++ compiler and using _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).
  • Conversion from a string results in a std::runtime_error being thrown if the string can not be interpreted as a valid floating-point number.
  • Division by zero results in an infinity being produced.
  • Type float128 can be used as a literal type (constexpr support).
  • Type 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.
  • When using the Intel compiler, the underlying type defaults to 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.
  • When the underlying type is Intel's _Quad type, the code must be compiled with the compiler option -Qoption,cpp,--extended_float_type.
  • When compiling with 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.
float128 example:
#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;
}


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


PrevUpHomeNext