...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
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&); int 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 */ }; }
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:
The actual arithmetic back-end that does all the work.
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:
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.
int128_t
to int256_t
, or cpp_dec_float_50
to cpp_dec_float_100
.
Type number
is explicitly
constructible from:
std::string
or any type which is convertible
to const char*
.
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:
number<Backend,
ExpressionTemplates>
.
number<Backend>
.
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:
*this < other
*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: 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:
number
.
number
.
number
has an implicit constructor - for example a fundamental
(built-in) arithmetic type.
The return type of these operators is either:
ExpressionTemplates
is
true
.
number<Backend,
et_off>
when ExpressionTemplates
is false
.
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).
template <class Backend, ExpressionTemplates> void swap(number<Backend, ExpressionTemplates>& a, number<Backend, ExpressionTemplates>& b);
Swaps a
and b
.
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.
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.
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&); int 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. |
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>
.
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.
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.
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.
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
).