[/ Copyright 2011 - 2020 John Maddock. Copyright 2013 - 2019 Paul A. Bristow. Copyright 2013 Christopher Kormanyos. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). ] [section:number number] [h4 Synopsis] namespace boost{ namespace multiprecision{ enum expression_template_option { et_on = 1, et_off = 0 }; template struct expression_template_default { static const expression_template_option value = et_on; }; template ::value> class number { public: typedef Backend backend_type; typedef typename component_type::type value_type; 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 T convert_to()const; template 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& o)const; template typename std::enable_if::value >, int>::type compare(const V& o)const; // real and imaginary parts: value_type real()const; value_type imag()const; template void real(const T& val); template 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 void swap(number& a, number& b); // iostream support: template std::ostream& operator << (std::ostream& os, const number& r); std::ostream& operator << (std::ostream& os, const ``['unmentionable-expression-template-type]``& r); template std::istream& operator >> (std::istream& is, number& r); // Arithmetic with a higher precision result: template ResultType& add(ResultType& result, const Source1& a, const Source2& b); template ResultType& subtract(ResultType& result, const Source1& a, const Source2& b); template 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 struct component_type; template struct number_category; template struct is_number; template 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 number sqrt(const ``['number-or-expression-template-type]``&, number&); template void divide_qr(const ``['number-or-expression-template-type]``& x, const ``['number-or-expression-template-type]``& y, number& q, number& r); template 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 bool bit_test(const number& val, unsigned index); template number& bit_set(number& val, unsigned index); template number& bit_unset(number& val, unsigned index); template number& bit_flip(number& val, unsigned index); template 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 struct numeric_limits > { /* Usual members here */ }; } [h4 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 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 ::value> class number; Class `number` has two template arguments: [variablelist [[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 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(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`. 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`. * An expression template derived from `number`. * Any type implicitly convertible to `number`, including some other instance of class `number`. For the left and right shift operations, the argument must be a __fundamental 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 T convert_to()const; template 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& o)const; template typename std::enable_if::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 void real(const T& val); template 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`. [h4 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 arithmetic type. The return type of these operators is either: * An ['unmentionable-type] expression template type when `ExpressionTemplates` is `true`. * Type `number` 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 integer type, and that the argument must be positive (negative arguments result in a `std::runtime_error` being thrown). [h4 swap] template void swap(number& a, number& b); Swaps `a` and `b`. [h4 Iostream Support] template std::ostream& operator << (std::ostream& os, const number& r); template std::ostream& operator << (std::ostream& os, const unmentionable-expression-template& r); template inline std::istream& operator >> (std::istream& is, number& 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. [h4 Arithmetic with a higher precision result] template ResultType& add(ResultType& result, const Source1& a, const Source2& b); template ResultType& subtract(ResultType& result, const Source1& a, const Source2& b); template 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. [h4 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]``&); 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` 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 `` 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_backend 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 [pi]. Also note that both __mpf_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): [table [[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[footnote It's likely that the inherent error in the input values to our test cases are to blame here.]][0eps][0eps]] [[sinh][2eps][0eps][0eps]] [[tanh][1eps][0eps][0eps]] [[pow][0eps][4eps][3eps]] [[atan2][1eps][0eps][0eps]] ] [h4 Traits Class Support] template 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 struct number_category; A traits class that inherits from `std::integral_constant` 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 arithmetic types as well as multiprecision ones. template struct is_number; A traits class that inherits from `std::integral_constant` if T is an instance of `number<>`, otherwise from `std::integral_constant`. template struct is_number_expression; A traits class that inherits from `std::integral_constant` if T is an expression template type derived from `number<>`, otherwise from `std::integral_constant`. [h4 Integer functions] In addition to functioning with types from this library, these functions are also overloaded for __fundamental integer types if you include ``. Further, when used with fixed precision types (whether __fundamental integers or multiprecision ones), the functions will promote to a wider type internally when the algorithm requires it. Versions overloaded for __fundamental 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 ['b[super p]] 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 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 ['b[super p] 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 number sqrt(const ``['number-or-expression-template-type]``& a, number& r); Returns the largest integer `x` such that `x * x < a`, and sets the remainder `r` such that `r = a - x * x`. template void divide_qr(const ``['number-or-expression-template-type]``& x, const ``['number-or-expression-template-type]``& y, number& q, number& r); Divides x by y and returns both the quotient and remainder. After the call `q = x / y` and `r = x % y`. template 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 bool bit_test(const number& val, unsigned index); Returns `true` if the bit at /index/ in /val/ is set. template number& bit_set(number& val, unsigned index); Sets the bit at /index/ in /val/, and returns /val/. template number& bit_unset(number& val, unsigned index); Unsets the bit at /index/ in /val/, and returns /val/. template number& bit_flip(number& val, unsigned index); Flips the bit at /index/ in /val/, and returns /val/. template 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. [h4 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. [h4 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. [h4 std::numeric_limits support] namespace std{ template struct numeric_limits > { /* 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`). [endsect]