843 lines
53 KiB
Plaintext
843 lines
53 KiB
Plaintext
[/
|
|
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 <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;
|
|
|
|
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);
|
|
|
|
// 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 */
|
|
};
|
|
|
|
}
|
|
|
|
[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 <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:
|
|
|
|
[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<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`.
|
|
|
|
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
|
|
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`.
|
|
|
|
[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<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 integer type,
|
|
and that the argument must be positive (negative arguments result in a `std::runtime_error` being thrown).
|
|
|
|
[h4 swap]
|
|
|
|
template <class Backend, ExpressionTemplates>
|
|
void swap(number<Backend, ExpressionTemplates>& a, number<Backend, ExpressionTemplates>& b);
|
|
|
|
Swaps `a` and `b`.
|
|
|
|
[h4 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.
|
|
|
|
[h4 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.
|
|
|
|
[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<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_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 <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 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>`.
|
|
|
|
|
|
[h4 Integer functions]
|
|
|
|
In addition to functioning with types from this library, these functions are also overloaded for __fundamental integer
|
|
types if you include `<boost/multiprecision/integer.hpp>`. 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 <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.
|
|
|
|
[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 <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`).
|
|
|
|
[endsect]
|