| Home | Libraries | People | FAQ | More

### 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
    {
    public:
       typedef          Backend                          backend_type;
       typedef typename component_type<self_type>::type  value_type;

       static constexpr expression_template_option et = ExpressionTemplates;

       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 std::enable_if<std::is_convertible<V, number<Backend, ExpressionTemplates>::value >, int>::type
          compare(const V& o)const;
       // real and imaginary parts:
       value_type real()const;
       value_type imag()const;
       template <class T>
       void real(const T& val);
       template <class T>
       void imag(const T& val);
       // 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);

    // to_string support:
    template <class Backend, expression_template_option ExpressionTemplates>
    std::string to_string(const number<Backend, ExpressionTemplates>& val);

    // 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);

    // min and max overloads:
    number                                    min    (const number-or-expression-template-type&, const number-or-expression-template-type&);
    number                                    max    (const number-or-expression-template-type&, const number-or-expression-template-type&);

    // C99 Non-member function standard library support:
    unmentionable-expression-template-type    abs        (const number-or-expression-template-type&);
    unmentionable-expression-template-type    acos       (const number-or-expression-template-type&);
    number                                    acosh      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    asin       (const number-or-expression-template-type&);
    number                                    asinh      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    atan       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    atan2      (const number-or-expression-template-type&, const number-or-expression-template-type&);
    number                                    atanh      (const number-or-expression-template-type&);
    number                                    cbrt       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    ceil       (const number-or-expression-template-type&);
    number                                    copysign   (const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    cos        (const number-or-expression-template-type&);
    unmentionable-expression-template-type    cosh       (const number-or-expression-template-type&);
    number                                    erf        (const number-or-expression-template-type&);
    number                                    erfc       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    exp        (const number-or-expression-template-type&);
    unmentionable-expression-template-type    exp2       (const number-or-expression-template-type&);
    number                                    expm1      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    fabs       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    fdim       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    floor      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    fma        (const number-or-expression-template-type&, const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    fmin       (const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    fmax       (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    frexp      (const number-or-expression-template-type&, integer-type*);
    unmentionable-expression-template-type    hypot      (const number-or-expression-template-type&, const number-or-expression-template-type&);
    integer-type                              ilogb      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    ldexp      (const number-or-expression-template-type&, integer-type);
    number                                    lgamma     (const number-or-expression-template-type&);
    long long                                 llrint     (const number-or-expression-template-type&);
    long long                                 llround    (const number-or-expression-template-type&);
    unmentionable-expression-template-type    log        (const number-or-expression-template-type&);
    unmentionable-expression-template-type    log2       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    log10      (const number-or-expression-template-type&);
    number                                    log1p      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    logb       (const number-or-expression-template-type&);
    long                                      lrint      (const number-or-expression-template-type&);
    long                                      lround     (const number-or-expression-template-type&);
    unmentionable-expression-template-type    modf       (const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    nearbyint  (const number-or-expression-template-type&);
    number                                    nextafter  (const number-or-expression-template-type&, const number-or-expression-template-type&);
    number                                    nexttoward (const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    pow        (const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    remainder  (const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    remquo     (const number-or-expression-template-type&, const number-or-expression-template-type&, int*);
    unmentionable-expression-template-type    rint       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    round      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    scalbn     (const number-or-expression-template-type&, integer-type);
    unmentionable-expression-template-type    scalbln    (const number-or-expression-template-type&, integer-type);
    unmentionable-expression-template-type    sin        (const number-or-expression-template-type&);
    unmentionable-expression-template-type    sinh       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    sqrt       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    tan        (const number-or-expression-template-type&);
    unmentionable-expression-template-type    tanh       (const number-or-expression-template-type&);
    number                                    tgamma     (const number-or-expression-template-type&);
    unmentionable-expression-template-type    trunc      (const number-or-expression-template-type&);

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

    bool                                      isgreater  (const number-or-expression-template-type&, const number-or-expression-template-type&);
    bool                                      isgreaterequal(const number-or-expression-template-type&, const number-or-expression-template-type&);
    bool                                      isless     (const number-or-expression-template-type&, const number-or-expression-template-type&);
    bool                                      islessequal(const number-or-expression-template-type&, const number-or-expression-template-typearea&);
    bool                                      islessgreater(const number-or-expression-template-type&, const number-or-expression-template-type&);
    bool                                      isunordered(const number-or-expression-template-type&, const number-or-expression-template-type&);
    // Complex number functions:
    number<...>::value_type                   real  (const number-or-expression-template-type&);
    number<...>::value_type                   imag  (const number-or-expression-template-type&);
    number<...>::value_type                   abs   (const number-or-expression-template-type&);
    number<...>::value_type                   arg   (const number-or-expression-template-type&);
    number<...>::value_type                   norm  (const number-or-expression-template-type&);
    number                                    conj  (const number-or-expression-template-type&);
    number                                    proj  (const number-or-expression-template-type&);
    number                                    polar (const number-or-expression-template-type&, const number-or-expression-template-type&);
    // Misc other common C library functions:
    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    iround (const number-or-expression-template-type&);
    number                                    changesign(const number-or-expression-template-type&);
    number                                    copysign(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    gcd(const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    lcm(const number-or-expression-template-type&, const number-or-expression-template-type&);
    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);
    unmentionable-expression-template-type    sqrt(const number-or-expression-template-type&);
    template <class Backend, expression_template_option ExpressionTemplates>
    number<Backend, EXpressionTemplates>      sqrt(const number-or-expression-template-type&, number<Backend, EXpressionTemplates>&);
    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);
    unsigned msb(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 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:

- Itself.
- An expression template which is the result of one of the arithmetic operators.
- Any fundamental (built-in) arithmetic type, as long as the result would not be lossy (for example float to integer conversion).
- Any type that the Backend is implicitly constructible or assignable from.
- An rvalue reference to another `number`. Move-semantics are used for construction if the backend also supports rvalue reference construction. In the case of assignment, move semantics are always supported when the argument is an rvalue reference irrespective of the backend.
- Any type in the same family, as long as no loss of precision is involved. For example from `int128_t` to `int256_t`, or `cpp_dec_float_50` to `cpp_dec_float_100`.

Type `number` is explicitly constructible from:

- Any type mentioned above.
- A `std::string` or any type which is convertible to `const char*`.
- Any arithmetic type (including those that would result in lossy conversions).
- Any type in the same family, including those that result in loss of precision.
- Any type that the Backend is explicitly constructible from.
- Any pair of types for which a generic interconversion exists: that is from integer to integer, integer to rational, integer to float, rational to rational, rational to float, or float to float.

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`. Rvalue forwarding overloads are provided so either one or both arguments may be rvalue-references which will be moved into the result, if the backend is able to make use of them.

Finally, when the type has a variable precision, then there are constructors:

    number(arg1, precision);
    number(arg1, arg2, precision);

Where `precision` is an unsigned value, the 2 arg version is active for scalar types and/or copy-construction with specific precision, and the 3-arg version for complex types.

Likewise `assign` has a 2-arg overloaded, with the second argument being the precision.

    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:

- Another `number<Backend, ExpressionTemplates>`.
- An expression template derived from `number<Backend>`.
- Any type implicitly convertible to `number<Backend, ExpressionTemplates>`, including some other instance of class `number`.

For the left and right shift operations, the argument must be a fundamental (built-in) 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 std::enable_if<std::is_convertible<V, number<Backend, ExpressionTemplates>::value >, int>::type
       compare(const V& other)const;

Returns:

- A value less that 0 for `*this < other`
- A value greater that 0 for `*this > other`

- Zero for `*this == other`

      value_type real()const;
      value_type imag()const;

These return the real and imaginary parts respectively. If the number is not a complex type, then the imaginary part is always zero.

    template <class T>
    void real(const T& val);
    template <class T>
    void imag(const T& val);

These set the real and imaginary parts respectively of the number. If the number is not a complex type, then setting the real part is equivalent to assignment, and attempting to set the imaginary part will result in a compile time error.

    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:

- A `number`.
- An expression template type derived from `number`.
- Any type for which `number` has an implicit constructor - for example a fundamental (built-in) arithmetic type.

The return type of these operators is either:

- An unmentionable-type expression template type when `ExpressionTemplates` is `true`.
- Type `number<Backend, et_off>` when `ExpressionTemplates` is `false`.
- Type `bool` if the operator is a comparison operator.

Finally note that the second argument to the left and right shift operations must be a fundamental (built-in) 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.

In addition, the C++11 `to_string` function is provided for use in generic code:

    template <class Backend, expression_template_option ExpressionTemplates>
    std::string to_string(const number<Backend, ExpressionTemplates>& val);

This a string with 6 digits of accuracy past the decimal point, matching the behavior of `std::to_string`. Note that this is a fixed precision representation, and hence monstrous strings can be returned.

##### 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    acos       (const number-or-expression-template-type&);
    number                                    acosh      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    asin       (const number-or-expression-template-type&);
    number                                    asinh      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    atan       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    atan2      (const number-or-expression-template-type&, const number-or-expression-template-type&);
    number                                    atanh      (const number-or-expression-template-type&);
    number                                    cbrt       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    ceil       (const number-or-expression-template-type&);
    number                                    copysign   (const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    cos        (const number-or-expression-template-type&);
    unmentionable-expression-template-type    cosh       (const number-or-expression-template-type&);
    number                                    erf        (const number-or-expression-template-type&);
    number                                    erfc       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    exp        (const number-or-expression-template-type&);
    unmentionable-expression-template-type    exp2       (const number-or-expression-template-type&);
    number                                    expm1      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    fabs       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    fdim       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    floor      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    fma        (const number-or-expression-template-type&, const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    fmin       (const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    fmax       (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    frexp      (const number-or-expression-template-type&, integer-type*);
    unmentionable-expression-template-type    hypot      (const number-or-expression-template-type&, const number-or-expression-template-type&);
    integer-type                              ilogb      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    ldexp      (const number-or-expression-template-type&, integer-type);
    number                                    lgamma     (const number-or-expression-template-type&);
    long long                                 llrint     (const number-or-expression-template-type&);
    long long                                 llround    (const number-or-expression-template-type&);
    unmentionable-expression-template-type    log        (const number-or-expression-template-type&);
    unmentionable-expression-template-type    log2       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    log10      (const number-or-expression-template-type&);
    number                                    log1p      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    logb       (const number-or-expression-template-type&);
    long                                      lrint      (const number-or-expression-template-type&);
    long                                      lround     (const number-or-expression-template-type&);
    unmentionable-expression-template-type    modf       (const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    nearbyint  (const number-or-expression-template-type&);
    number                                    nextafter  (const number-or-expression-template-type&, const number-or-expression-template-type&);
    number                                    nexttoward (const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    pow        (const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    remainder  (const number-or-expression-template-type&, const number-or-expression-template-type&);
    unmentionable-expression-template-type    remquo     (const number-or-expression-template-type&, const number-or-expression-template-type&, int*);
    unmentionable-expression-template-type    rint       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    round      (const number-or-expression-template-type&);
    unmentionable-expression-template-type    scalbn     (const number-or-expression-template-type&, integer-type);
    unmentionable-expression-template-type    scalbln    (const number-or-expression-template-type&, integer-type);
    unmentionable-expression-template-type    sin        (const number-or-expression-template-type&);
    unmentionable-expression-template-type    sinh       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    sqrt       (const number-or-expression-template-type&);
    unmentionable-expression-template-type    tan        (const number-or-expression-template-type&);
    unmentionable-expression-template-type    tanh       (const number-or-expression-template-type&);
    number                                    tgamma     (const number-or-expression-template-type&);
    unmentionable-expression-template-type    trunc      (const number-or-expression-template-type&);

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

    bool                                      isgreater  (const number-or-expression-template-type&, const number-or-expression-template-type&);
    bool                                      isgreaterequal(const number-or-expression-template-type&, const number-or-expression-template-type&);
    bool                                      isless     (const number-or-expression-template-type&, const number-or-expression-template-type&);
    bool                                      islessequal(const number-or-expression-template-type&, const number-or-expression-template-type&);
    bool                                      islessgreater(const number-or-expression-template-type&, const number-or-expression-template-type&);
    bool                                      isunordered(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 unless otherwise stated.

The integer type arguments to `ldexp`, `frexp`, `scalbn` and `ilogb` may be either type `int`, or the actual type of the exponent of the number type.

Complex number types support the following functions:

    // Complex number functions:
    number<...>::value_type                   real  (const number-or-expression-template-type&);
    number<...>::value_type                   imag  (const number-or-expression-template-type&);
    number<...>::value_type                   abs   (const number-or-expression-template-type&);
    number<...>::value_type                   arg   (const number-or-expression-template-type&);
    number<...>::value_type                   norm  (const number-or-expression-template-type&);
    number                                    conj  (const number-or-expression-template-type&);
    number                                    proj  (const number-or-expression-template-type&);
    number                                    polar (const number-or-expression-template-type&, const number-or-expression-template-type&);

In addition the functions `real`, `imag`, `arg`, `norm`, `conj` and `proj` are overloaded for scalar (ie non-complex) types in the same manner as `<complex>` and treat the argument as a value whose imaginary part is zero.

There are also some functions implemented for compatibility with the Boost.Math functions of the same name:

    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    iround (const number-or-expression-template-type&);
    number                                    changesign(const number-or-expression-template-type&);
    number                                    copysign(const number-or-expression-template-type&, const number-or-expression-template-type&);

All 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 `std::integral_constant<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 fundamental (built-in) arithmetic types as well as multiprecision ones.

    template <class T>
    struct is_number;

A traits class that inherits from `std::integral_constant<bool, true>` if T is an instance of `number<>`, otherwise from `std::integral_constant<bool, false>`.

    template <class T>
    struct is_number_expression;

A traits class that inherits from `std::integral_constant<bool, true>` if T is an expression template type derived from `number<>`, otherwise from `std::integral_constant<bool, false>`.

##### Integer functions

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

    unmentionable-expression-template-type    gcd(const number-or-expression-template-type& a, const number-or-expression-template-type& b);

Returns the largest integer `x` that divides both `a` and `b`.

    unmentionable-expression-template-type    lcm(const number-or-expression-template-type& a, const number-or-expression-template-type& b);

Returns the smallest integer `x` that is divisible by both `a` and `b`.

    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 fundamental (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.

    unmentionable-expression-template-type    sqrt(const number-or-expression-template-type& a);

Returns the largest integer `x` such that `x * x < a`.

    template <class Backend, expression_template_option ExpressionTemplates>
    number<Backend, EXpressionTemplates>      sqrt(const number-or-expression-template-type& a, number<Backend, EXpressionTemplates>& r);

Returns the largest integer `x` such that `x * x < a`, and sets the remainder `r` such that `r = a - x * x`.

    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 (zero-based) index of the least significant bit that is set to 1.

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

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

Returns the (zero-based) index of the most significant bit.

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`).