diff --git a/doc/html/boost_multiprecision/intro.html b/doc/html/boost_multiprecision/intro.html new file mode 100644 index 00000000..6a2d9aaf --- /dev/null +++ b/doc/html/boost_multiprecision/intro.html @@ -0,0 +1,476 @@ + +
+ +
+ The Multiprecision library comes in two distinct parts: an expression-template-enabled
+ front end mp_number that handles
+ all the operator overloading, expression evaluation optimization, and code
+ reduction, and a selection of backends that implement the actual arithmetic
+ operations, and need conform only to the reduced interface requirements of
+ the front end.
+
+ The library is often used by using one of the predfined typedefs: for example + if you wanted an arbitrary precision integer type using GMP as the underlying + implementation then you could use: +
+#include <boost/multiprecision/gmp.hpp> // Defines the wrappers around the GMP library's types + +boost::multiprecision::mpz_int myint; // Arbitrary precision integer type. ++
+ Alternatively one can compose your own multiprecision type, by combining mp_number with one of the predefined backend
+ types. For example, suppose you wanted a 300 decimal digit floating point type
+ based on the MPFR library, in this case there's no predefined typedef with
+ that level of precision, so instead we compose our own:
+
#include <boost/multiprecision/mpfr.hpp> // Defines the Backend type that wraps MPFR + +namespace mp = boost::multiprecision; // Reduce the typing a bit later... + +typedef mp::mp_number<mp::mpfr_float_backend<300> > my_float; + +my_float a, b, c; // These variables have 300 decimal digits precision ++
+ Class mp_number is expression-template-enabled:
+ that means that rather than having a multiplication operator that looks like
+ this:
+
template <class Backend> +mp_number<Backend> operator * (const mp_number<Backend>& a, const mp_number<Backend>& b) +{ + mp_number<Backend> result(a); + result *= b; + return result; +} ++
+ Instead the operator looks more like this: +
+template <class Backend> +unmentionable-type operator * (const mp_number<Backend>& a, const mp_number<Backend>& b); ++
+ Where the "unmentionable" return type is an implementation detail + that, rather than containing the result of the multiplication, contains instructions + on how to compute the result. In effect it's just a pair of references to the + arguments of the function, plus some compile-time information that stores what + the operation is. +
+
+ The great advantage of this method is the elimination of temporaries:
+ for example the "naive" implementation of operator* above, requires one temporary for computing
+ the result, and at least another one to return it. It's true that sometimes
+ this overhead can be reduced by using move-semantics, but it can't be eliminated
+ completely. For example, lets suppose we're evaluating a polynomial via Horners
+ method, something like this:
+
T a[7] = { /* some values */ }; +//.... +y = (((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]; ++
+ If type T is an mp_number, then this expression is evaluated
+ without creating a single temporary value, in contrast
+ if we were using the C++ wrapper that ships with GMP - mpf_class
+ - then this expression would result in no less than 11 temporaries (this is
+ true even though mpf_class does use expression templates to reduce the number
+ of temporaries somewhat). Had we used an even simpler wrapper around GMP or
+ MPFR like mpclass things would
+ have been even worse and no less that 24 temporaries are created for this simple
+ expression (note - we actually measure the number of memory allocations performed
+ rather than the number of temporaries directly).
+
+ This library also extends expression template support to standard library functions
+ like abs or sin
+ with mp_number arguments. This
+ means that an expression such as:
+
y = abs(x); ++
+ can be evaluated without a single temporary being calculated. Even expressions + like: +
+y = sin(x); ++
+ get this treatment, so that variable 'y' is used as "working storage"
+ within the implementation of sin,
+ thus reducing the number of temporaries used by one. Of course, should you
+ write:
+
x = sin(x); ++
+ Then we clearly can't use x
+ as working storage during the calculation, so then a temporary variable is
+ created in this case.
+
+ Given the comments above, you might be forgiven for thinking that expression-templates
+ are some kind of universal-panacea: sadly though, all tricks like this have
+ their downsides. For one thing, expression template libraries like this one,
+ tend to be slower to compile than their simpler cousins, they're also harder
+ to debug (should you actually want to step through our code!), and rely on
+ compiler optimizations being turned on to give really good performance. Also
+ since the return type from expressions involving mp_number's
+ is an "unmentionable implementation detail", you have to be careful
+ to cast the result of an expression to the actual number type when passing
+ an expression to a template function. For example given:
+
template <class T> +void my_proc(const T&); ++
+ Then calling: +
+my_proc(a+b); ++
+ Will very likely result in obscure error messages inside the body of my_proc - since we've passed it an expression
+ template type, and not a number type. Instead we probably need:
+
my_proc(my_mp_number_type(a+b)); ++
+ Having said that, these situations don't occur that often - or indeed not at + all for non-template functions. In addition all the functions in the Boost.Math + library will automatically convert expression-template arguments to the underlying + number type without you having to do anything, so: +
+mpfr_float_100 a(20), delta(0.125); +boost::math::gamma_p(a, a + delta); ++
+ Will work just fine, with the a + delta expression
+ template argument getting converted to an mpfr_float_100
+ internally by the Boost.Math library.
+
+ One other potential pitfall that's only possible in C++11: you should never + store an expression template using: +
+auto my_expression = a + b - c; ++
+ Unless you're absolutely sure that the lifetimes of a,
+ b and c
+ will outlive that of my_expression.
+
+ And finally.... the performance improvements from an expression template library
+ like this are often not as dramatic as the reduction in number of temporaries
+ would suggest. For example if we compare this library with mpfr_class
+ and mpreal, with all three
+ using the underlying MPFR library at 50 decimal digits precision then we see
+ the following typical results for polynomial execution:
+
Table 1.1. Evaluation of Order 6 Polynomial.
+|
+ + Library + + |
+
+ + Relative Time + + |
+
+ + Relative number of memory allocations + + |
+
|---|---|---|
|
+ + mp_number + + |
+
+ + 1.0 (0.00793s) + + |
+
+ + 1.0 (2996 total) + + |
+
|
+ + mpfr_class + + |
+
+ + 1.2 (0.00931s) + + |
+
+ + 4.3 (12976 total) + + |
+
|
+ + mpreal + + |
+
+ + 1.9 (0.0148s) + + |
+
+ + 9.3 (27947 total) + + |
+
+ As you can see the execution time increases a lot more slowly than the number + of memory allocations. There are a number of reasons for this: +
+operator*=) tends to be more than an out-of-place
+ operator*
+ (typically operator *=
+ has to create a temporary workspace to carry out the multiplication, where
+ as operator*
+ can use the target variable as workspace). Since the expression templates
+ carry out their magic by converting out-of-place operators to in-place
+ ones, we necessarily take this hit. Even so the transformation is more
+ efficient than creating the extra temporary variable, just not by as much
+ as one would hope.
+ + We'll conclude this section by providing some more performance comparisons + between these three libraries, again, all are using MPFR to carry out the underlying + arithmetic, and all are operating at the same precision (50 decimal places): +
+Table 1.2. Evaluation of Boost.Math's Bessel function test data
+|
+ + Library + + |
+
+ + Relative Time + + |
+
+ + Relative Number of Memory Allocations + + |
+
|---|---|---|
|
+ + mp_number + + |
+
+ + 1.0 (6.21s) + + |
+
+ + 1.0 (2685469) + + |
+
|
+ + mpfr_class + + |
+
+ + 1.04 (6.45s) + + |
+
+ + 1.47 (3946007) + + |
+
|
+ + mpreal + + |
+
+ + 1.53 (9.52s) + + |
+
+ + 4.92 (13222940) + + |
+
Table 1.3. Evaluation of Boost.Math's Non-Central T distribution test data
+|
+ + Library + + |
+
+ + Relative Time + + |
+
+ + Relative Number of Memory Allocations + + |
+
|---|---|---|
|
+ + mp_number + + |
+
+ + 1.0 (269s) + + |
+
+ + 1.0 (139082551) + + |
+
|
+ + mpfr_class + + |
+
+ + 1.04 (278s) + + |
+
+ + 1.81 (252400791) + + |
+
|
+ + mpreal + + |
+
+ + 1.49 (401s) + + |
+
+ + 3.22 (447009280) + + |
+
| + | + |
| + | + |
+ The requirements on the Backend
+ template argument to mp_number
+ are split up into compulsary requirements, and optional requirements that
+ are either to improve performance or provide optional features.
+
+ In the following tables, type B is the Backend
+ template arument to mp_number,
+ b is a variable of B, cb and cb2
+ are constant variables of type B, a
+ is a variable of Arithmetic type, s
+ is a variable of type const char*, ui is a variable of type unsigned, bb
+ is a variable of type bool,
+ pa is a variable of type
+ pointer-to-arithmetc-type, exp
+ is a variable of type B::exp_type, pexp
+ is a variable of type B::exp_type*.
+
Table 1.4. Compulsary Requirements on the Backend type.
+|
+ + Expression + + |
+
+ + Return Type + + |
+
+ + Comments + + |
+
|---|---|---|
|
+
+ |
+
+
+ |
+
+
+ A list of signed integral types that can be assigned to type B.
+ The types shall be listed in order of size, smallest first, and
+ shall terminate in the type that is |
+
|
+
+ |
+
+
+ |
+
+
+ A list of unsigned integral types that can be assigned to type
+ B. The types shall be listed in order of size, smallest first,
+ and shall terminate in the type that is |
+
|
+
+ |
+
+
+ |
+
+
+ A list of floating point types that can be assigned to type B.The
+ types shall be listed in order of size, smallest first, and shall
+ terminate in type |
+
|
+
+ |
+
+ + A signed integral type. + + |
+
+ + The type of the exponent of type B. + + |
+
|
+
+ |
++ | +
+ + Default constructor. + + |
+
|
+
+ |
++ | +
+ + Copy Constructor. + + |
+
|
+
+ |
+
+
+ |
+
+ + Assignment operator. + + |
+
|
+
+ |
+
+
+ |
+
+
+ Assignment from an Arithmetic type. The type of |
+
|
+
+ |
+
+
+ |
+
+ + Assignment from a string. + + |
+
|
+
+ |
+
+
+ |
+
+ + Swaps the contents of it's arguments. + + |
+
|
+
+ |
+
+
+ |
+
+
+ Returns the string representation of |
+
|
+
+ |
+
+
+ |
+
+
+ Negates |
+
|
+
+ |
+
+
+ |
+
+
+ Compares |
+
|
+
+ |
+
+
+ |
+
+
+ Compares |
+
|
+
+ |
+
+
+ |
+
+
+ Adds |
+
|
+
+ |
+
+
+ |
+
+
+ Subtracts |
+
|
+
+ |
+
+
+ |
+
+
+ Multiplies |
+
|
+
+ |
+
+
+ |
+
+
+ Divides |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes the ones-complement of |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Converts |
+
|
+
+ |
+
+
+ |
+
+
+ Stores values in |
+
|
+
+ |
+
+
+ |
+
+
+ Stores a value in |
+
|
+
+ |
+
+
+ |
+
+
+ Stores the floor of |
+
|
+
+ |
+
+
+ |
+
+
+ Stores the ceiling of |
+
|
+
+ |
+
+
+ |
+
+
+ Stores the square root of |
+
Table 1.5. Optional Requirements on the Backend Type
+|
+ + Expression + + |
+
+ + Returns + + |
+
+ + Comments + + |
+
|---|---|---|
|
+
+ |
+
+
+ |
+
+
+ Adds |
+
|
+
+ |
+
+
+ |
+
+
+ Subtracts |
+
|
+
+ |
+
+
+ |
+
+
+ Multiplies |
+
|
+
+ |
+
+
+ |
+
+
+ Divides |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Add |
+
|
+
+ |
+
+
+ |
+
+
+ Subtracts |
+
|
+
+ |
+
+
+ |
+
+
+ Multiplies |
+
|
+
+ |
+
+
+ |
+
+
+ Divides |
+
|
+
+ |
+
+
+ |
+
+
+ Add |
+
|
+
+ |
+
+
+ |
+
+
+ Subtracts |
+
|
+
+ |
+
+
+ |
+
+
+ Multiplies |
+
|
+
+ |
+
+
+ |
+
+
+ Divides |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Add |
+
|
+
+ |
+
+
+ |
+
+
+ Subtracts |
+
|
+
+ |
+
+
+ |
+
+
+ Multiplies |
+
|
+
+ |
+
+
+ |
+
+
+ Divides |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+
+ |
+
+
+ Computes |
+
|
+
+ |
+
+ + void + + |
+
+
+ Increments the value of |
+
|
+
+ |
+
+ + void + + |
+
+
+ Decrements the value of |
+
|
+
+ |
+
+
+ |
+
+
+ Returns |
+
|
+
+ |
+
+
+ |
+
+
+ Returns a value < zero if |
+
|
+
+ |
+
+
+ |
+
+
+ Set |
+
|
+
+ |
+
+
+ |
+
+
+ Set |
+
|
+
+ |
+
+
+ |
+
+
+ Returns one of the same values returned by |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
|
+
+ |
+
+
+ |
+
+
+ Performs the equivalent operation to |
+
| + | + |
namespace boost{ namespace multiprecision{ + +template <class Backend> +class mp_number +{ + mp_number(); + mp_number(see-below); + mp_number& operator=(see-below); + + /* Other number-type operators here */ + + // Use in Boolean context: + operator convertible-to-bool-type()const; + // swap: + void swap(mp_number& other); + // Sign: + bool is_zero()const; + int sign()const; + // string conversion: + std::string str()const; + // Generic conversion mechanism + template <class T> + T convert_to()const; + // precision control: + static unsigned default_precision(); + static void default_precision(unsigned digits10); + unsigned precision()const; + void precision(unsigned digits10); + // Comparison: + int compare(const mp_number<Backend>& o)const; + template <class V> + typename enable_if<is_arithmetic<V>, int>::type compare(const V& o)const; + // Access to the underlying implementation: + Backend& backend(); + const Backend& backend()const; +}; + +// Swap: +template <class Backend> +void swap(mp_number<Backend>& a, mp_number<Backend>& b); + +// iostream support: +template <class Backend> +std::ostream& operator << (std::ostream& os, const mp_number<Backend>& r); +std::ostream& operator << (std::ostream& os, const unmentionable-expression-template-type& r); +template <class Backend> +std::istream& operator >> (std::istream& is, mp_number<Backend>& r); + +// Non-member function standard library support: +unmentionable-expression-template-type abs (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type fabs (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type sqrt (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type floor (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type ceil (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type trunc (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type itrunc (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type ltrunc (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type lltrunc(const mp_number-or-expression-template-type&); +unmentionable-expression-template-type round (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type iround (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type lround (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type llround(const mp_number-or-expression-template-type&); +unmentionable-expression-template-type exp (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type log (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type log10 (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type cos (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type sin (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type tan (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type acos (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type asin (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type atan (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type cosh (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type sinh (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type tanh (const mp_number-or-expression-template-type&); + +unmentionable-expression-template-type ldexp (const mp_number-or-expression-template-type&, int); +unmentionable-expression-template-type frexp (const mp_number-or-expression-template-type&, int*); +unmentionable-expression-template-type pow (const mp_number-or-expression-template-type&, const mp_number-or-expression-template-type&); +unmentionable-expression-template-type fmod (const mp_number-or-expression-template-type&, const mp_number-or-expression-template-type&); +unmentionable-expression-template-type atan2 (const mp_number-or-expression-template-type&, const mp_number-or-expression-template-type&); + +}} // namespaces + +namespace boost{ namespace math{ + +// Boost.Math interoperability functions: +int fpclassify (const mp_number-or-expression-template-type&, int); +bool isfinite (const mp_number-or-expression-template-type&, int); +bool isnan (const mp_number-or-expression-template-type&, int); +bool isinf (const mp_number-or-expression-template-type&, int); +bool isnormal (const mp_number-or-expression-template-type&, int); + +}} // namespaces + +// numeric_limits support: +namespace std{ + +template <class Backend> +struct numeric_limits<boost::multiprecision<Backend> > +{ + /* Usual members here */ +}; + +} ++
mp_number(); +mp_number(see-below); +mp_number& operator=(see-below); ++
+ Type mp_number is default
+ constructible, and both copy constructible and assignable from:
+
std::string or any type which is convertible
+ to const char*.
+ /* Other number-type operators here */
+
++ The following arithmetic operations are support for real-numbered types: +
+, -, *, /,
+ ==, !, <, >, <, >, ||, &&,
+ ||, &&=.
+ + For integer types the following operators are also supported: +
+
+ Binary %, %, |, |, &, &, ^, ^,
+ <<, <<, >>, >>.
+
+ Note that with the exception of the logical operators and unary + the result + of applying an operator to mp_number is an "unmentionable" expression + template type. +
+
+ Binary operators, must have at least one argument that is of type mp_number or an expression template derived
+ from mp_number. One argument
+ may optionally be of arithmetic type.
+
+ Note that type mp_number
+ (and all expression templates derived from it) may be used in a Boolian context.
+
operator convertible-to-bool-type()const; ++
+ Returns an unmentionable-type that is usable in Boolean
+ contexts (this allows mp_number
+ to be used in any Boolean context - if statements, conditional statements,
+ or as an argument to a logical operator - without type mp_number
+ being convertible to type bool.
+
void swap(mp_number& other); ++
+ Swaps *this
+ with other.
+
bool is_zero()const; ++
+ Returns true is *this is zero,
+ otherwise false.
+
int sign()const; ++
+ Returns a value less than zero if *this is negative, a value greater than zero
+ if *this
+ is positive, and zero if *this
+ is zero.
+
std::string str(unsigned precision, bool scientific = true)const; ++
+ Returns the number formatted as a string, with at least precision + digits, and in scientific format if scientific is true. +
+template <class T> +T convert_to()const; ++
+ Provides a generic conversion mechanism to convert *this to type T.
+ Type T may be any arithmetic
+ type. Optionally other types may also be supported by specific Backend types.
+
static unsigned default_precision(); +static void default_precision(unsigned digits10); +unsigned precision()const; +void precision(unsigned digits10); ++
+ These functions are only available if the Backend template parameter supports
+ runtime changes to precision. They get and set the default precision and
+ the precision of *this
+ respectively.
+
int compare(const mp_number<Backend>& o)const; +template <class V> +typename enable_if<is_arithmetic<V>, int>::type compare(const V& other)const; ++
+ Returns: +
+Backend& backend(); +const Backend& backend()const; ++
+ Returns the underlying backend instance used by *this. +
+template <class Backend> +void swap(mp_number<Backend>& a, mp_number<Backend>& b); ++
+ Swaps a and b.
+
template <class Backend> +std::ostream& operator << (std::ostream& os, const mp_number<Backend>& r); +template <class Backend> +std::ostream& operator << (std::ostream& os, const unmentionable-expression-template& r); +template <class Backend> +inline std::istream& operator >> (std::istream& is, mp_number<Backend>& r) ++
+ These operators provided formatted input-output operations on mp_number types, and expression templates
+ derived from them.
+
unmentionable-expression-template-type abs (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type fabs (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type sqrt (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type floor (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type ceil (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type trunc (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type itrunc (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type ltrunc (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type lltrunc(const mp_number-or-expression-template-type&); +unmentionable-expression-template-type round (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type iround (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type lround (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type llround(const mp_number-or-expression-template-type&); +unmentionable-expression-template-type exp (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type log (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type log10 (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type cos (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type sin (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type tan (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type acos (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type asin (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type atan (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type cosh (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type sinh (const mp_number-or-expression-template-type&); +unmentionable-expression-template-type tanh (const mp_number-or-expression-template-type&); + +unmentionable-expression-template-type ldexp (const mp_number-or-expression-template-type&, int); +unmentionable-expression-template-type frexp (const mp_number-or-expression-template-type&, int*); +unmentionable-expression-template-type pow (const mp_number-or-expression-template-type&, const mp_number-or-expression-template-type&); +unmentionable-expression-template-type fmod (const mp_number-or-expression-template-type&, const mp_number-or-expression-template-type&); +unmentionable-expression-template-type atan2 (const mp_number-or-expression-template-type&, const mp_number-or-expression-template-type&); ++
+ These functions all behave exactly as their standard library counterparts
+ do: their argument is either an instance of mp_number
+ or an expression template derived from it; their return value is always an
+ expression template.
+
+ These functions are normally implemented by the Backend type. However, default + versions are provided for Backend types that don't have native support for + these functions. Please note however, that this default support requires + the precision of the type to be a compile time constant - this means for + example that the GMP MPF Backend will not work with these functions when + that type is used at variable precision. +
+
+ Also note that with the exception of abs
+ that these functions can only be used with floating point Backend types.
+
namespace boost{ namespace math{ + +int fpclassify (const mp_number-or-expression-template-type&, int); +bool isfinite (const mp_number-or-expression-template-type&, int); +bool isnan (const mp_number-or-expression-template-type&, int); +bool isinf (const mp_number-or-expression-template-type&, int); +bool isnormal (const mp_number-or-expression-template-type&, int); + +}} // namespaces ++
+ These functions behave exacts as their Boost.Math equivalents. Other Boost.Math + functions and templates may also be specialized or overloaded to ensure interoperability. +
+namespace std{ + +template <class Backend> +struct numeric_limits<boost::multiprecision<Backend> > +{ + /* Usual members here */ +}; + +} ++
+ Class template std::numeric_limits is specialized for all instantiations
+ of mp_number whose precision
+ is known at compile time, plus those types whose precision is unlimited (though
+ it is much less useful in those cases). It is not specialized for types whose
+ precision can vary at compile time (such as mpf_float).
+
| + | + |
+ In order to use this library you need to make two choices: what kind of number + do I want, and which backend do I want to perform the actual arithmetic? +
+| + | + |
+ The following backends provide integer arithmetic: +
+|
+ + Backend Type + + |
+
+ + Header + + |
+
+ + Radix + + |
+
+ + Dependencies + + |
+
+ + Pros + + |
+
+ + Cons + + |
+
|---|---|---|---|---|---|
|
+
+ |
+
+ + boost/multiprecision/gmp.hpp + + |
+
+ + 2 + + |
+
+ + GMP + + |
+
+ + Very fast and efficient backend. + + |
+
+ + Dependency on GNU licenced GMP library. + + |
+
namespace boost{ namespace multiprecision{ + +class gmp_int; + +typedef mp_number<gmp_int > mpz_int; + +}} // namespaces ++
+ The gmp_int backend is used
+ via the typedef boost::multiprecision::mpz_int. It acts as a thin wrapper around
+ the GMP mpz_t to provide
+ an integer type that is a drop-in replacement for the native C++ integer
+ types, but with unlimited precision.
+
+ As well as the usual conversions from arithmetic and string types, type
+ mpz_int is copy constructible
+ and asignable from:
+
mpf_t,
+ mpz_t, mpq_t.
+ mp_number<T> that are wrappers around those types:
+ mp_number<gmp_float<N> >, mp_number<gmp_rational>.
+
+ It's also possible to access the underlying mpz_t
+ via the data() member function of gmp_int.
+
+ +
+#include <boost/multiprecision/gmp.hpp> + +using namespace boost::multiprecision; + +mpz_int v = 1; + +// Do some arithmetic: +for(unsigned i = 1; i <= 1000; ++i) + v *= i; + +std::cout << v << std::endl; // prints 1000! + +// Access the underlying representation: +mpz_t z; +mpz_init(z); +mpz_set(z, v.backend().data()); ++
+
+| + | + |
+ The following backends provide rational number arithmetic: +
+|
+ + Backend Type + + |
+
+ + Header + + |
+
+ + Radix + + |
+
+ + Dependencies + + |
+
+ + Pros + + |
+
+ + Cons + + |
+
|---|---|---|---|---|---|
|
+
+ |
+
+ + boost/multiprecision/gmp.hpp + + |
+
+ + 2 + + |
+
+ + GMP + + |
+
+ + Very fast and efficient backend. + + |
+
+ + Dependency on GNU licenced GMP library. + + |
+
namespace boost{ namespace multiprecision{ + +class gmp_rational; + +typedef mp_number<gmp_rational > mpq_rational; + +}} // namespaces ++
+ The gmp_rational backend
+ is used via the typedef boost::multiprecision::mpq_rational.
+ It acts as a thin wrapper around the GMP mpq_t
+ to provide a rational number type that is a drop-in replacement for the native
+ C++ number types, but with unlimited precision.
+
+ As well as the usual conversions from arithmetic and string types, instances
+ of mp_number<gmp_rational>
+ are copy constructible and assignable from:
+
mpz_t,
+ mpq_t.
+ mp_number<gmp_int>.
+ + There are also non-member functions: +
+mpz_int numerator(const mpq_rational&); +mpz_int denominator(const mpq_rational&); ++
+ Which return the numerator and denominator of the number. +
+
+ It's also possible to access the underlying mpq_t
+ via the data() member function of mpq_rational.
+
+ +
+#include <boost/multiprecision/gmp.hpp> + +using namespace boost::multiprecision; + +mpq_rational v = 1; + +// Do some arithmetic: +for(unsigned i = 1; i <= 1000; ++i) + v *= i; +v /= 10; + +std::cout << v << std::endl; // prints 1000! / 10 +std::cout << numerator(v) << std::endl; +std::cout << denominator(v) << std::endl; + +// Access the underlying data: +mpq_t q; +mpq_init(q); +mpq_set(q, v.backend().data()); ++
+
+| + | + |
+ The following backends provide real number arithmetic: +
+|
+ + Backend Type + + |
+
+ + Header + + |
+
+ + Radix + + |
+
+ + Dependencies + + |
+
+ + Pros + + |
+
+ + Cons + + |
+
|---|---|---|---|---|---|
|
+
+ |
+
+ + boost/multiprecision/gmp.hpp + + |
+
+ + 2 + + |
+
+ + GMP + + |
+
+ + Very fast and efficient backend. + + |
+
+ + Dependency on GNU licenced GMP library. + + |
+
|
+
+ |
+
+ + boost/multiprecision/mpfr.hpp + + |
+
+ + 2 + + |
+
+ + GMP and MPFR + + |
+
+ + Very fast and efficient backend, with it's own standard library + implementation. + + |
+
+ + Dependency on GNU licenced GMP and MPFR libraries. + + |
+
|
+
+ |
+
+ + boost/multiprecision/cpp_float.hpp + + |
+
+ + 10 + + |
+
+ + None + + |
+
+ + Header only, all C++ implementation. + + |
+
+ + Approximately 2x slower than the MPFR or GMP libraries. + + |
+
namespace boost{ namespace multiprecision{ + +template <unsigned Digits10> +class gmp_float; + +typedef mp_number<gmp_float<50> > mpf_float_50; +typedef mp_number<gmp_float<100> > mpf_float_100; +typedef mp_number<gmp_float<500> > mpf_float_500; +typedef mp_number<gmp_float<1000> > mpf_float_1000; +typedef mp_number<gmp_float<0> > mpf_float; + +}} // namespaces ++
+ The gmp_float backend is
+ used in conjunction with mp_number:
+ It acts as a thin wrapper around the GMP mpf_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 gmp_float 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 mpf_float_50, mpf_float_100, mpf_float_500, mpf_float_1000
+ provide arithmetic types at 50, 100, 500 and 1000 decimal digits precision
+ respectively. The typedef mpf_float provides a variable precision type whose
+ precision can be controlled via the mp_number's
+ member functions.
+
![]() |
+Note | +
|---|---|
+ This type only provides standard library and |
+ As well as the usual conversions from arithmetic and string types, instances
+ of mp_number<mpf_float<N> > are copy constructible and assignable
+ from:
+
mpf_t,
+ mpz_t, mpq_t.
+ mp_number wrappers
+ around those types: mp_number<mpf_float<M> >,
+ mp_number<gmp_int>,
+ mp_number<gmp_rational>.
+
+ It's also possible to access the underlying mpf_t
+ via the data() member function of gmp_float.
+
+ +
+#include <boost/multiprecision/gmp.hpp> + +using namespace boost::multiprecision; + +// Operations at variable precision and limited standard library support: +mpf_float a = 2; +mpf_float::default_precision(1000); +std::cout << mpf_float::default_precision() << std::endl; +std::cout << sqrt(a) << std::endl; // print root-2 + +// Operations at fixed precision and full standard library support: +mpf_float_100 b = 2; +std::cout << std::numeric_limits<mpf_float_100>::digits << std::endl; +std::cout << log(b) << std::endl; // print log(2) + +// Access the underlying representation: +mpf_t f; +mpf_init(f); +mpf_set(f, a.backend().data()); ++
+
+namespace boost{ namespace multiprecision{ + +template <unsigned Digits10> +class mpfr_float_backend; + +typedef mp_number<mpfr_float_backend<50> > mpfr_float_50; +typedef mp_number<mpfr_float_backend<100> > mpfr_float_100; +typedef mp_number<mpfr_float_backend<500> > mpfr_float_500; +typedef mp_number<mpfr_float_backend<1000> > mpfr_float_1000; +typedef mp_number<mpfr_float_backend<0> > mpfr_float; + +}} // namespaces ++
+ The mpfr_float_backend type
+ is used in conjunction with mp_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 mp_number's
+ member functions.
+
![]() |
+Note | +
|---|---|
+ This type only provides |
+ As well as the usual conversions from arithmetic and string types, instances
+ of mp_number<mpfr_float_backend<N> > are copy constructible and assignable
+ from:
+
mpf_t,
+ mpz_t, mpq_t.
+ mpfr_t.
+ mp_number wrappers
+ around those types: mp_number<mpfr_float_backend<M> >,
+ mp_number<mpf_float<M> >, mp_number<gmp_int>, mp_number<gmp_rational>.
+
+ It's also possible to access the underlying mpf_t
+ via the data() member function of gmp_float.
+
+ +
+#include <boost/multiprecision/mpfr.hpp> + +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; +std::cout << log(b) << std::endl; // print log(2) + +// Access the underlying data: +mpfr_t r; +mpfr_init(r); +mpfr_set(r, b.backend().data(), GMP_RNDN); ++
+
+namespace boost{ namespace multiprecision{ + +template <unsigned Digits10> +class cpp_float; + +typedef mp_number<cpp_float<50> > cpp_float_50; +typedef mp_number<cpp_float<100> > cpp_float_100; + +}} // namespaces ++
+ The cpp_float backend is
+ used in conjunction with mp_number:
+ It acts as an entirely C++ (header only and dependency free) real-number
+ type that is a drop-in replacement for the native C++ floating-point types,
+ but with much greater precision.
+
+ Type cpp_float can be used
+ at fixed precision by specifying a non-zero Digits10
+ template parameter. The typedefs cpp_float_50 and cpp_float_100 provide arithmetic
+ types at 50 and 100 decimal digits precision respectively.
+
+ There is full standard library and numeric_limits
+ support available for this type.
+
+ +
+#include <boost/multiprecision/cpp_float.hpp> + +using namespace boost::multiprecision; + +// Operations at fixed precision and full numeric_limits support: +cpp_float_100 b = 2; +std::cout << std::numeric_limits<cpp_float_100>::digits << std::endl; +std::cout << log(b) << std::endl; // print log(2) ++
+
+| + | + |
Copyright © 2011 John Maddock
+ Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +
+Table of Contents
+ +Last revised: July 08, 2011 at 18:51:46 +0100 |
++ |