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

mpfr_float

#include <boost/multiprecision/mpfr.hpp>

namespace boost{ namespace multiprecision{

enum mpfr_allocation_type
{
   allocate_stack,
   allocate_dynamic
};

template <unsigned Digits10, mpfr_allocation_type AllocateType = allocate_dynamic>
class mpfr_float_backend;

typedef number<mpfr_float_backend<50> >    mpfr_float_50;
typedef number<mpfr_float_backend<100> >   mpfr_float_100;
typedef number<mpfr_float_backend<500> >   mpfr_float_500;
typedef number<mpfr_float_backend<1000> >  mpfr_float_1000;
typedef number<mpfr_float_backend<0> >     mpfr_float;

typedef number<mpfr_float_backend<50, allocate_stack> >    static_mpfr_float_50;
typedef number<mpfr_float_backend<100, allocate_stack> >   static_mpfr_float_100;

}} // namespaces

The mpfr_float_backend type is used in conjunction with number: It acts as a thin wrapper around the MPFR mpfr_t to provide an real-number type that is a drop-in replacement for the native C++ floating-point types, but with much greater precision.

Type mpfr_float_backend can be used at fixed precision by specifying a non-zero Digits10 template parameter, or at variable precision by setting the template argument to zero. The typedefs mpfr_float_50, mpfr_float_100, mpfr_float_500, mpfr_float_1000 provide arithmetic types at 50, 100, 500 and 1000 decimal digits precision respectively. The typedef mpfr_float provides a variable precision type whose precision can be controlled via the numbers member functions.

In addition the second template parameter lets you choose between dynamic allocation (the default, and uses MPFR's normal allocation routines), or stack allocation (where all the memory required for the underlying data types is stored within mpfr_float_backend). The latter option can result in significantly faster code, at the expense of growing the size of mpfr_float_backend. It can only be used at fixed precision, and should only be used for lower digit counts. Note that we can not guarantee that using allocate_stack won't cause any calls to mpfr's allocation routines, as mpfr may call these inside it's own code. The following table gives an idea of the performance tradeoff's at 50 decimal digits precision[2]:

Type

Bessel function evaluation, relative times

number<mpfr_float_backend<50, allocate_static>, et_on>

1.0 (5.5s)

number<mpfr_float_backend<50, allocate_static>, et_off>

1.05 (5.8s)

number<mpfr_float_backend<50, allocate_dynamic>, et_on>

1.05 (5.8s)

number<mpfr_float_backend<50, allocate_dynamic>, et_off>

1.16 (6.4s)

[Note] Note

This type only provides numeric_limits support when the precision is fixed at compile time.

As well as the usual conversions from arithmetic and string types, instances of number<mpfr_float_backend<N> > are copy constructible and assignable from:

It's also possible to access the underlying mpfr_t via the data() member function of mpfr_float_backend.

Things you should know when using this type:

MPFR example:
#include <boost/multiprecision/mpfr.hpp>
#include <boost/math/special_functions/gamma.hpp>
#include <iostream>

int main()
{
   using namespace boost::multiprecision;

   // Operations at variable precision and no numeric_limits support:
   mpfr_float a = 2;
   mpfr_float::default_precision(1000);
   std::cout << mpfr_float::default_precision() << std::endl;
   std::cout << sqrt(a) << std::endl; // print root-2

   // Operations at fixed precision and full numeric_limits support:
   mpfr_float_100 b = 2;
   std::cout << std::numeric_limits<mpfr_float_100>::digits << std::endl;
   // We can use any C++ std lib function:
   std::cout << log(b) << std::endl; // print log(2)
   // We can also use any function from Boost.Math:
   std::cout << boost::math::tgamma(b) << std::endl;
   // These even work when the argument is an expression template:
   std::cout << boost::math::tgamma(b * b) << std::endl;

   // Access the underlying data:
   mpfr_t r;
   mpfr_init(r);
   mpfr_set(r, b.backend().data(), GMP_RNDN);
   mpfr_clear(r);
   return 0;
}


[2] Compiled with VC++10 and /Ox, with MPFR-3.0.0 and MPIR-2.3.0


PrevUpHomeNext