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

This is the documentation for an old version of Boost. Click here to view this page for the latest version.
PrevUpHomeNext

number

Synopsis
namespace boost{ namespace multiprecision{

enum expression_template_option { et_on = 1, et_off = 0 };

template <class Backend> struct expression_template_default
{ static const expression_template_option value = et_on; };

template <class Backend, expression_template_option ExpressionTemplates = expression_template_default<Backend>::value>
class number
{
   number();
   number(see-below);
   number& operator=(see-below);
   number& assign(see-below);

   // Member operators
   number& operator+=(const see-below&);
   number& operator-=(const see-below&);
   number& operator*=(const see-below&);
   number& operator/=(const see-below&);
   number& operator++();
   number& operator--();
   number  operator++(int);
   number  operator--(int);

   number& operator%=(const see-below&);
   number& operator&=(const see-below&);
   number& operator|=(const see-below&);
   number& operator^=(const see-below&);
   number& operator<<=(const integer-type&);
   number& operator>>=(const integer-type&);

   // Use in Boolean context:
   operator convertible-to-bool-type()const;
   // swap:
   void swap(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;
   template <class T>
   explicit operator T ()const;
   // precision control:
   static unsigned default_precision();
   static void default_precision(unsigned digits10);
   unsigned precision()const;
   void precision(unsigned digits10);
   // Comparison:
   int compare(const number<Backend>& o)const;
   template <class V>
   typename enable_if<is_convertible<V, number<Backend, ExpressionTemplates> >, int>::type
      compare(const V& o)const;
   // Access to the underlying implementation:
   Backend& backend();
   const Backend& backend()const;
};

// Non member operators:
unmentionable-expression-template-type operator+(const see-below&);
unmentionable-expression-template-type operator-(const see-below&);
unmentionable-expression-template-type operator+(const see-below&, const see-below&);
unmentionable-expression-template-type operator-(const see-below&, const see-below&);
unmentionable-expression-template-type operator*(const see-below&, const see-below&);
unmentionable-expression-template-type operator/(const see-below&, const see-below&);
// Integer only operations:
unmentionable-expression-template-type operator%(const see-below&, const see-below&);
unmentionable-expression-template-type operator&(const see-below&, const see-below&);
unmentionable-expression-template-type operator|(const see-below&, const see-below&);
unmentionable-expression-template-type operator^(const see-below&, const see-below&);
unmentionable-expression-template-type operator<<(const see-below&, const integer-type&);
unmentionable-expression-template-type operator>>(const see-below&, const integer-type&);
// Comparison operators:
bool operator==(const see-below&, const see-below&);
bool operator!=(const see-below&, const see-below&);
bool operator< (const see-below&, const see-below&);
bool operator> (const see-below&, const see-below&);
bool operator<=(const see-below&, const see-below&);
bool operator>=(const see-below&, const see-below&);

// Swap:
template <class Backend, expression_template_option ExpressionTemplates>
void swap(number<Backend, ExpressionTemplates>& a, number<Backend, ExpressionTemplates>& b);

// iostream support:
template <class Backend, expression_template_option ExpressionTemplates>
std::ostream& operator << (std::ostream& os, const number<Backend, ExpressionTemplates>& r);
std::ostream& operator << (std::ostream& os, const unmentionable-expression-template-type& r);
template <class Backend, expression_template_option ExpressionTemplates>
std::istream& operator >> (std::istream& is, number<Backend, ExpressionTemplates>& r);

// Arithmetic with a higher precision result:
template <class ResultType, class Source1 class Source2>
ResultType& add(ResultType& result, const Source1& a, const Source2& b);
template <class ResultType, class Source1 class Source2>
ResultType& subtract(ResultType& result, const Source1& a, const Source2& b);
template <class ResultType, class Source1 class Source2>
ResultType& multiply(ResultType& result, const Source1& a, const Source2& b);

// Non-member function standard library support:
unmentionable-expression-template-type    abs    (const number-or-expression-template-type&);
unmentionable-expression-template-type    fabs   (const number-or-expression-template-type&);
unmentionable-expression-template-type    sqrt   (const number-or-expression-template-type&);
unmentionable-expression-template-type    floor  (const number-or-expression-template-type&);
unmentionable-expression-template-type    ceil   (const number-or-expression-template-type&);
unmentionable-expression-template-type    trunc  (const number-or-expression-template-type&);
unmentionable-expression-template-type    itrunc (const number-or-expression-template-type&);
unmentionable-expression-template-type    ltrunc (const number-or-expression-template-type&);
unmentionable-expression-template-type    lltrunc(const number-or-expression-template-type&);
unmentionable-expression-template-type    round  (const number-or-expression-template-type&);
unmentionable-expression-template-type    iround (const number-or-expression-template-type&);
unmentionable-expression-template-type    lround (const number-or-expression-template-type&);
unmentionable-expression-template-type    llround(const number-or-expression-template-type&);
unmentionable-expression-template-type    exp    (const number-or-expression-template-type&);
unmentionable-expression-template-type    log    (const number-or-expression-template-type&);
unmentionable-expression-template-type    log10    (const number-or-expression-template-type&);
unmentionable-expression-template-type    cos    (const number-or-expression-template-type&);
unmentionable-expression-template-type    sin    (const number-or-expression-template-type&);
unmentionable-expression-template-type    tan    (const number-or-expression-template-type&);
unmentionable-expression-template-type    acos   (const number-or-expression-template-type&);
unmentionable-expression-template-type    asin   (const number-or-expression-template-type&);
unmentionable-expression-template-type    atan   (const number-or-expression-template-type&);
unmentionable-expression-template-type    cosh   (const number-or-expression-template-type&);
unmentionable-expression-template-type    sinh   (const number-or-expression-template-type&);
unmentionable-expression-template-type    tanh   (const number-or-expression-template-type&);

unmentionable-expression-template-type    ldexp (const number-or-expression-template-type&, int);
unmentionable-expression-template-type    frexp (const number-or-expression-template-type&, int*);
unmentionable-expression-template-type    pow   (const number-or-expression-template-type&, const number-or-expression-template-type&);
unmentionable-expression-template-type    fmod  (const number-or-expression-template-type&, const number-or-expression-template-type&);
unmentionable-expression-template-type    atan2 (const number-or-expression-template-type&, const number-or-expression-template-type&);

// Traits support:
template <class T>
struct component_type;
template <class T>
struct number_category;
template <class T>
struct is_number;
template <class T>
struct is_number_expression;

// Integer specific functions:
unmentionable-expression-template-type    pow(const number-or-expression-template-type&, unsigned);
unmentionable-expression-template-type    powm(const number-or-expression-template-type& b, const number-or-expression-template-type& p, const number-or-expression-template-type& m);
template <class Backend, expression_template_option ExpressionTemplates>
void divide_qr(const number-or-expression-template-type& x, const number-or-expression-template-type& y,
               number<Backend, ExpressionTemplates>& q, number<Backend, ExpressionTemplates>& r);
template <class Integer>
Integer integer_modulus(const number-or-expression-template-type& x, Integer val);
unsigned lsb(const number-or-expression-template-type& x);
template <class Backend, class ExpressionTemplates>
bool bit_test(const number<Backend, ExpressionTemplates>& val, unsigned index);
template <class Backend, class ExpressionTemplates>
number<Backend, ExpressionTemplates>& bit_set(number<Backend, ExpressionTemplates>& val, unsigned index);
template <class Backend, class ExpressionTemplates>
number<Backend, ExpressionTemplates>& bit_unset(number<Backend, ExpressionTemplates>& val, unsigned index);
template <class Backend, class ExpressionTemplates>
number<Backend, ExpressionTemplates>& bit_flip(number<Backend, ExpressionTemplates>& val, unsigned index);
template <class Engine>
bool miller_rabin_test(const number-or-expression-template-type& n, unsigned trials, Engine& gen);
bool miller_rabin_test(const number-or-expression-template-type& n, unsigned trials);

// Rational number support:
typename component_type<number-or-expression-template-type>::type numerator  (const number-or-expression-template-type&);
typename component_type<number-or-expression-template-type>::type denominator(const number-or-expression-template-type&);

}} // namespaces

namespace boost{ namespace math{

// Boost.Math interoperability functions:
int                                              fpclassify     (const number-or-expression-template-type&, int);
bool                                             isfinite       (const number-or-expression-template-type&, int);
bool                                             isnan          (const number-or-expression-template-type&, int);
bool                                             isinf          (const number-or-expression-template-type&, int);
bool                                             isnormal       (const number-or-expression-template-type&, int);

}} // namespaces

// numeric_limits support:
namespace std{

template <class Backend, expression_template_option ExpressionTemplates>
struct numeric_limits<boost::multiprecision<Backend, ExpressionTemplates> >
{
   /* Usual members here */
};

}
Description
enum expression_template_option { et_on = 1, et_off = 0 };

This enumerated type is used to specify whether expression templates are turned on (et_on) or turned off (et_off).

template <class Backend> struct expression_template_default
{ static const expression_template_option value = et_on; };

This traits class specifies the default expression template option to be used with a particular Backend type. It defaults to et_on.

template <class Backend, expression_template_option ExpressionTemplates = expression_template_default<Backend>::value>
class number;

Class number has two template arguments:

Backend

The actual arithmetic back-end that does all the work.

ExpressionTemplates

A Boolean value: when et_on, then expression templates are enabled, otherwise when set to et_off they are disabled. The default for this parameter is computed via the traits class expression_template_default whose member value defaults to et_on unless the the traits class is specialized for a particular backend.

number();
number(see-below);
number& operator=(see-below);
number& assign(see-below);

Type number is default constructible, and both copy constructible and assignable from:

Type number is explicitly constructible from:

The assign member function is available for any type for which an explicit converting constructor exists. It is intended to be used where a temporary generated from an explicit assignment would be expensive, for example:

mpfr_float_50    f50;
mpfr_float_100   f100;

f50 = static_cast<mpfr_float_50>(f100);  // explicit cast create a temporary
f50.assign(f100);                        // explicit call to assign create no temporary

In addition, if the type has multiple components (for example rational or complex number types), then there is a two argument constructor:

number(arg1, arg2);

Where the two args must either be arithmetic types, or types that are convertible to the two components of this.

number& operator+=(const see-below&);
number& operator-=(const see-below&);
number& operator*=(const see-below&);
number& operator/=(const see-below&);
number& operator++();
number& operator--();
number  operator++(int);
number  operator--(int);
// Integer only operations:
number& operator%=(const see-below&);
number& operator&=(const see-below&);
number& operator|=(const see-below&);
number& operator^=(const see-below&);
number& operator<<=(const integer-type&);
number& operator>>=(const integer-type&);

These operators all take their usual arithmetic meanings.

The arguments to these operators is either:

For the left and right shift operations, the argument must be a builtin integer type with a positive value (negative values result in a std::runtime_error being thrown).

operator convertible-to-bool-type()const;

Returns an unmentionable-type that is usable in Boolean contexts (this allows number to be used in any Boolean context - if statements, conditional statements, or as an argument to a logical operator - without type number being convertible to type bool.

This operator also enables the use of number with any of the following operators: !, ||, && and ?:.

void swap(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;

template <class T>
explicit operator T ()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 number<Backend, ExpressionTemplates>& o)const;
template <class V>
typename enable_if<is_convertible<V, number<Backend, ExpressionTemplates> >, int>::type
   compare(const V& other)const;

Returns:

Backend& backend();
const Backend& backend()const;

Returns the underlying back-end instance used by *this.

Non-member operators
// Non member operators:
unmentionable-expression-template-type operator+(const see-below&);
unmentionable-expression-template-type operator-(const see-below&);
unmentionable-expression-template-type operator+(const see-below&, const see-below&);
unmentionable-expression-template-type operator-(const see-below&, const see-below&);
unmentionable-expression-template-type operator*(const see-below&, const see-below&);
unmentionable-expression-template-type operator/(const see-below&, const see-below&);
// Integer only operations:
unmentionable-expression-template-type operator%(const see-below&, const see-below&);
unmentionable-expression-template-type operator&(const see-below&, const see-below&);
unmentionable-expression-template-type operator|(const see-below&, const see-below&);
unmentionable-expression-template-type operator^(const see-below&, const see-below&);
unmentionable-expression-template-type operator<<(const see-below&, const integer-type&);
unmentionable-expression-template-type operator>>(const see-below&, const integer-type&);
// Comparison operators:
bool operator==(const see-below&, const see-below&);
bool operator!=(const see-below&, const see-below&);
bool operator< (const see-below&, const see-below&);
bool operator> (const see-below&, const see-below&);
bool operator<=(const see-below&, const see-below&);
bool operator>=(const see-below&, const see-below&);

These operators all take their usual arithmetic meanings.

The arguments to these functions must contain at least one of the following:

The return type of these operators is either:

Finally note that the second argument to the left and right shift operations must be a builtin integer type, and that the argument must be positive (negative arguments result in a std::runtime_error being thrown).

swap
template <class Backend, ExpressionTemplates>
void swap(number<Backend, ExpressionTemplates>& a, number<Backend, ExpressionTemplates>& b);

Swaps a and b.

Iostream Support
template <class Backend, expression_template_option ExpressionTemplates>
std::ostream& operator << (std::ostream& os, const number<Backend, ExpressionTemplates>& r);
template <class Unspecified...>
std::ostream& operator << (std::ostream& os, const unmentionable-expression-template& r);
template <class Backend, expression_template_option ExpressionTemplates>
inline std::istream& operator >> (std::istream& is, number<Backend, ExpressionTemplates>& r)

These operators provided formatted input-output operations on number types, and expression templates derived from them.

It's down to the back-end type to actually implement string conversion. However, the back-ends provided with this library support all of the iostream formatting flags, field width and precision settings.

Arithmetic with a higher precision result
template <class ResultType, class Source1 class Source2>
ResultType& add(ResultType& result, const Source1& a, const Source2& b);

template <class ResultType, class Source1 class Source2>
ResultType& subtract(ResultType& result, const Source1& a, const Source2& b);

template <class ResultType, class Source1 class Source2>
ResultType& multiply(ResultType& result, const Source1& a, const Source2& b);

These functions apply the named operator to the arguments a and b and store the result in result, returning result. In all cases they behave "as if" arguments a and b were first promoted to type ResultType before applying the operator, though particular backends may well avoid that step by way of an optimization.

The type ResultType must be an instance of class number, and the types Source1 and Source2 may be either instances of class number or native integer types. The latter is an optimization that allows arithmetic to be performed on native integer types producing an extended precision result.

Non-member standard library function support
unmentionable-expression-template-type    abs    (const number-or-expression-template-type&);
unmentionable-expression-template-type    fabs   (const number-or-expression-template-type&);
unmentionable-expression-template-type    sqrt   (const number-or-expression-template-type&);
unmentionable-expression-template-type    floor  (const number-or-expression-template-type&);
unmentionable-expression-template-type    ceil   (const number-or-expression-template-type&);
unmentionable-expression-template-type    trunc  (const number-or-expression-template-type&);
unmentionable-expression-template-type    itrunc (const number-or-expression-template-type&);
unmentionable-expression-template-type    ltrunc (const number-or-expression-template-type&);
unmentionable-expression-template-type    lltrunc(const number-or-expression-template-type&);
unmentionable-expression-template-type    round  (const number-or-expression-template-type&);
unmentionable-expression-template-type    iround (const number-or-expression-template-type&);
unmentionable-expression-template-type    lround (const number-or-expression-template-type&);
unmentionable-expression-template-type    llround(const number-or-expression-template-type&);
unmentionable-expression-template-type    exp    (const number-or-expression-template-type&);
unmentionable-expression-template-type    log    (const number-or-expression-template-type&);
unmentionable-expression-template-type    log10    (const number-or-expression-template-type&);
unmentionable-expression-template-type    cos    (const number-or-expression-template-type&);
unmentionable-expression-template-type    sin    (const number-or-expression-template-type&);
unmentionable-expression-template-type    tan    (const number-or-expression-template-type&);
unmentionable-expression-template-type    acos   (const number-or-expression-template-type&);
unmentionable-expression-template-type    asin   (const number-or-expression-template-type&);
unmentionable-expression-template-type    atan   (const number-or-expression-template-type&);
unmentionable-expression-template-type    cosh   (const number-or-expression-template-type&);
unmentionable-expression-template-type    sinh   (const number-or-expression-template-type&);
unmentionable-expression-template-type    tanh   (const number-or-expression-template-type&);

unmentionable-expression-template-type    ldexp (const number-or-expression-template-type&, int);
unmentionable-expression-template-type    frexp (const number-or-expression-template-type&, int*);
unmentionable-expression-template-type    pow   (const number-or-expression-template-type&, const number-or-expression-template-type&);
unmentionable-expression-template-type    fmod  (const number-or-expression-template-type&, const number-or-expression-template-type&);
unmentionable-expression-template-type    atan2 (const number-or-expression-template-type&, const number-or-expression-template-type&);

These functions all behave exactly as their standard library C++11 counterparts do: their argument is either an instance of number or an expression template derived from it; If the argument is of type number<Backend, et_off> then that is also the return type, otherwise the return type is 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 (if any other types such as fixed precision or complex types are added to the library later, then these functions may be extended to support those number types).

The precision of these functions is generally determined by the backend implementation. For example the precision of these functions when used with mpfr_float is determined entirely by MPFR. When these functions use our own implementations, the accuracy of the transcendental functions is generally a few epsilon. Note however, that the trigonometrical functions incur the usual accuracy loss when reducing arguments by large multiples of π. Also note that both gmp_float and cpp_dec_float have a number of guard digits beyond their stated precision, so the error rates listed for these are in some sense artificially low.

The following table shows the error rates we observe for these functions with various backend types, functions not listed here are exact (tested on Win32 with VC++10, MPFR-3.0.0, MPIR-2.1.1):

Function

mpfr_float_50

mpf_float_50

cpp_dec_float_50

sqrt

1eps

0eps

0eps

exp

1eps

0eps

0eps

log

1eps

0eps

0eps

log10

1eps

0eps

0eps

cos

700eps

0eps

0eps

sin

1eps

0eps

0eps

tan

0eps

0eps

0eps

acos

0eps

0eps

0eps

asin

0eps

0eps

0eps

atan

1eps

0eps

0eps

cosh

1045eps[1]

0eps

0eps

sinh

2eps

0eps

0eps

tanh

1eps

0eps

0eps

pow

0eps

4eps

3eps

atan2

1eps

0eps

0eps

[1] It's likely that the inherent error in the input values to our test cases are to blame here.

Traits Class Support
template <class T>
struct component_type;

If this is a type with multiple components (for example rational or complex types), then this trait has a single member type that is the type of those components.

template <class T>
struct number_category;

A traits class that inherits from mpl::int_<N> where N is one of the enumerated values number_kind_integer, number_kind_floating_point, number_kind_rational, number_kind_fixed_point, or number_kind_unknown. This traits class is specialized for any type that has std::numeric_limits support as well as for classes in this library: which means it can be used for generic code that must work with built in arithmetic types as well as multiprecision ones.

template <class T>
struct is_number;

A traits class that inherits from mpl::true_ if T is an instance of number<>, otherwise from mpl::false_.

template <class T>
struct is_number_expression;

A traits class that inherits from mpl::true_ if T is an expression template type derived from number<>, otherwise from mpl::false_.

Integer functions

In addition to functioning with types from this library, these functions are also overloaded for built in integer types if you include <boost/multiprecision/integer.hpp>. Further, when used with fixed precision types (whether built in integers or multiprecision ones), the functions will promote to a wider type internally when the algorithm requires it. Versions overloaded for built in integer types return that integer type rather than an expression template.

unmentionable-expression-template-type    pow(const number-or-expression-template-type& b, unsigned p);

Returns bp as an expression template. Note that this function should be used with extreme care as the result can grow so large as to take "effectively forever" to compute, or else simply run the host machine out of memory. This is the one function in this category that is not overloaded for built in integer types, further, it's probably not a good idea to use it with fixed precision cpp_int's either.

unmentionable-expression-template-type    powm(const number-or-expression-template-type& b, const number-or-expression-template-type& p, const number-or-expression-template-type& m);

Returns bp mod m as an expression template. Fixed precision types are promoted internally to ensure accuracy.

template <class Backend, expression_template_option ExpressionTemplates>
void divide_qr(const number-or-expression-template-type& x, const number-or-expression-template-type& y,
               number<Backend, ExpressionTemplates>& q, number<Backend, ExpressionTemplates>& r);

Divides x by y and returns both the quotient and remainder. After the call q = x / y and r = x % y.

template <class Integer>
Integer integer_modulus(const number-or-expression-template-type& x, Integer val);

Returns the absolute value of x % val.

unsigned lsb(const number-or-expression-template-type& x);

Returns the index of the least significant bit that is set to 1.

Throws a std::range_error if the argument is <= 0.

template <class Backend, class ExpressionTemplates>
bool bit_test(const number<Backend, ExpressionTemplates>& val, unsigned index);

Returns true if the bit at index in val is set.

template <class Backend, class ExpressionTemplates>
number<Backend, ExpressionTemplates>& bit_set(number<Backend, ExpressionTemplates>& val, unsigned index);

Sets the bit at index in val, and returns val.

template <class Backend, class ExpressionTemplates>
number<Backend, ExpressionTemplates>& bit_unset(number<Backend, ExpressionTemplates>& val, unsigned index);

Unsets the bit at index in val, and returns val.

template <class Backend, class ExpressionTemplates>
number<Backend, ExpressionTemplates>& bit_flip(number<Backend, ExpressionTemplates>& val, unsigned index);

Flips the bit at index in val, and returns val.

template <class Engine>
bool miller_rabin_test(const number-or-expression-template-type& n, unsigned trials, Engine& gen);
bool miller_rabin_test(const number-or-expression-template-type& n, unsigned trials);

Tests to see if the number n is probably prime - the test excludes the vast majority of composite numbers by excluding small prime factors and performing a single Fermat test. Then performs trials Miller-Rabin tests. Returns false if n is definitely composite, or true if n is probably prime with the probability of it being composite less than 0.25^trials. Fixed precision types are promoted internally to ensure accuracy.

Rational Number Functions
typename component_type<number-or-expression-template-type>::type numerator  (const number-or-expression-template-type&);
typename component_type<number-or-expression-template-type>::type denominator(const number-or-expression-template-type&);

These functions return the numerator and denominator of a rational number respectively.

Boost.Math Interoperability Support
namespace boost{ namespace math{

int  fpclassify     (const number-or-expression-template-type&, int);
bool isfinite       (const number-or-expression-template-type&, int);
bool isnan          (const number-or-expression-template-type&, int);
bool isinf          (const number-or-expression-template-type&, int);
bool isnormal       (const number-or-expression-template-type&, int);

}} // namespaces

These floating-point classification functions behave exactly as their Boost.Math equivalents.

Other Boost.Math functions and templates may also be specialized or overloaded to ensure interoperability.

std::numeric_limits support
namespace std{

template <class Backend, ExpressionTemplates>
struct numeric_limits<boost::multiprecision<Backend, ExpressionTemplates> >
{
   /* Usual members here */
};

}

Class template std::numeric_limits is specialized for all instantiations of 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).


PrevUpHomeNext