Constant gmp_mpfr_sys::C::GMP::CPP_Class_Interface [−][src]
pub const CPP_Class_Interface: ();
This constant is a place-holder for documentation; do not use it in code.
Next: Custom Allocation, Previous: Formatted Input, Up: Top [Index]
12 C++ Class Interface
This chapter describes the C++ class based interface to GMP.
All GMP C language types and functions can be used in C++ programs, since
gmp.h has extern "C" qualifiers, but the class interface offers
overloaded functions and operators which may be more convenient.
Due to the implementation of this interface, a reasonably recent C++ compiler is required, one supporting namespaces, partial specialization of templates and member templates.
Everything described in this chapter is to be considered preliminary and might be subject to incompatible changes if some unforeseen difficulty reveals itself.
| • C++ Interface General | ||
| • C++ Interface Integers | ||
| • C++ Interface Rationals | ||
| • C++ Interface Floats | ||
| • C++ Interface Random Numbers | ||
| • C++ Interface Limitations |
Next: C++ Interface Integers, Previous: C++ Class Interface, Up: C++ Class Interface [Index]
12.1 C++ Interface General
All the C++ classes and functions are available with
#include <gmpxx.h>
Programs should be linked with the libgmpxx and libgmp libraries. For example,
g++ mycxxprog.cc -lgmpxx -lgmp
The classes defined are
- Class: mpz_class
- Class: mpq_class
- Class: mpf_class
The standard operators and various standard functions are overloaded to allow arithmetic with these classes. For example,
int
main (void)
{
mpz_class a, b, c;
a = 1234;
b = "-5678";
c = a+b;
cout << "sum is " << c << "\n";
cout << "absolute value is " << abs(c) << "\n";
return 0;
}
An important feature of the implementation is that an expression like
a=b+c results in a single call to the corresponding mpz_add,
without using a temporary for the b+c part. Expressions which by their
nature imply intermediate values, like a=b*c+d*e, still use temporaries
though.
The classes can be freely intermixed in expressions, as can the classes and
the standard types long, unsigned long and double.
Smaller types like int or float can also be intermixed, since
C++ will promote them.
Note that bool is not accepted directly, but must be explicitly cast to
an int first. This is because C++ will automatically convert any
pointer to a bool, so if GMP accepted bool it would make all
sorts of invalid class and pointer combinations compile but almost certainly
not do anything sensible.
Conversions back from the classes to standard C++ types aren’t done
automatically, instead member functions like get_si are provided (see
the following sections for details).
Also there are no automatic conversions from the classes to the corresponding GMP C types, instead a reference to the underlying C object can be obtained with the following functions,
- Function: mpz_t mpz_class::get_mpz_t ()
- Function: mpq_t mpq_class::get_mpq_t ()
- Function: mpf_t mpf_class::get_mpf_t ()
These can be used to call a C function which doesn’t have a C++ class
interface. For example to set a to the GCD of b and c,
mpz_class a, b, c; ... mpz_gcd (a.get_mpz_t(), b.get_mpz_t(), c.get_mpz_t());
In the other direction, a class can be initialized from the corresponding GMP C type, or assigned to if an explicit constructor is used. In both cases this makes a copy of the value, it doesn’t create any sort of association. For example,
mpz_t z; // ... init and calculate z ... mpz_class x(z); mpz_class y; y = mpz_class (z);
There are no namespace setups in gmpxx.h, all types and functions are simply put into the global namespace. This is what gmp.h has done in the past, and continues to do for compatibility. The extras provided by gmpxx.h follow GMP naming conventions and are unlikely to clash with anything.
Next: C++ Interface Rationals, Previous: C++ Interface General, Up: C++ Class Interface [Index]
12.2 C++ Interface Integers
- Function: mpz_class::mpz_class (type n)
Construct an
mpz_class. All the standard C++ types may be used, exceptlong longandlong double, and all the GMP C++ classes can be used, although conversions frommpq_classandmpf_classareexplicit. Any necessary conversion follows the corresponding C function, for exampledoublefollowsmpz_set_d(see Assigning Integers).
- Function: explicit mpz_class::mpz_class (const mpz_t z)
Construct an
mpz_classfrom anmpz_t. The value in z is copied into the newmpz_class, there won’t be any permanent association between it and z.
- Function: explicit mpz_class::mpz_class (const char *s, int base = 0)
- Function: explicit mpz_class::mpz_class (const string& s, int base = 0)
Construct an
mpz_classconverted from a string usingmpz_set_str(see Assigning Integers).If the string is not a valid integer, an
std::invalid_argumentexception is thrown. The same applies tooperator=.
- Function: mpz_class operator"" _mpz (const char *str)
With C++11 compilers, integers can be constructed with the syntax
123_mpzwhich is equivalent tompz_class("123").
- Function: mpz_class operator/ (mpz_class a, mpz_class d)
- Function: mpz_class operator% (mpz_class a, mpz_class d)
Divisions involving
mpz_classround towards zero, as per thempz_tdiv_qandmpz_tdiv_rfunctions (see Integer Division). This is the same as the C99/and%operators.The
mpz_fdiv…ormpz_cdiv…functions can always be called directly if desired. For example,mpz_class q, a, d; ... mpz_fdiv_q (q.get_mpz_t(), a.get_mpz_t(), d.get_mpz_t());
- Function: mpz_class abs (mpz_class op)
- Function: int cmp (mpz_class op1, type op2)
- Function: int cmp (type op1, mpz_class op2)
- Function: bool mpz_class::fits_sint_p (void)
- Function: bool mpz_class::fits_slong_p (void)
- Function: bool mpz_class::fits_sshort_p (void)
- Function: bool mpz_class::fits_uint_p (void)
- Function: bool mpz_class::fits_ulong_p (void)
- Function: bool mpz_class::fits_ushort_p (void)
- Function: double mpz_class::get_d (void)
- Function: long mpz_class::get_si (void)
- Function: string mpz_class::get_str (int base = 10)
- Function: unsigned long mpz_class::get_ui (void)
- Function: int mpz_class::set_str (const char *str, int base)
- Function: int mpz_class::set_str (const string& str, int base)
- Function: int sgn (mpz_class op)
- Function: mpz_class sqrt (mpz_class op)
- Function: mpz_class gcd (mpz_class op1, mpz_class op2)
- Function: mpz_class lcm (mpz_class op1, mpz_class op2)
- Function: mpz_class mpz_class::factorial (type op)
- Function: mpz_class factorial (mpz_class op)
- Function: mpz_class mpz_class::primorial (type op)
- Function: mpz_class primorial (mpz_class op)
- Function: mpz_class mpz_class::fibonacci (type op)
- Function: mpz_class fibonacci (mpz_class op)
- Function: void mpz_class::swap (mpz_class& op)
- Function: void swap (mpz_class& op1, mpz_class& op2)
These functions provide a C++ class interface to the corresponding GMP C routines. Calling
factorialorprimorialon a negative number is undefined.cmpcan be used with any of the classes or the standard C++ types, exceptlong longandlong double.
Overloaded operators for combinations of mpz_class and double
are provided for completeness, but it should be noted that if the given
double is not an integer then the way any rounding is done is currently
unspecified. The rounding might take place at the start, in the middle, or at
the end of the operation, and it might change in the future.
Conversions between mpz_class and double, however, are defined
to follow the corresponding C functions mpz_get_d and mpz_set_d.
And comparisons are always made exactly, as per mpz_cmp_d.
Next: C++ Interface Floats, Previous: C++ Interface Integers, Up: C++ Class Interface [Index]
12.3 C++ Interface Rationals
In all the following constructors, if a fraction is given then it should be in
canonical form, or if not then mpq_class::canonicalize called.
- Function: mpq_class::mpq_class (type op)
- Function: mpq_class::mpq_class (integer num, integer den)
Construct an
mpq_class. The initial value can be a single value of any type (conversion frommpf_classisexplicit), or a pair of integers (mpz_classor standard C++ integer types) representing a fraction, except thatlong longandlong doubleare not supported. For example,mpq_class q (99); mpq_class q (1.75); mpq_class q (1, 3);
- Function: explicit mpq_class::mpq_class (const mpq_t q)
Construct an
mpq_classfrom anmpq_t. The value in q is copied into the newmpq_class, there won’t be any permanent association between it and q.
- Function: explicit mpq_class::mpq_class (const char *s, int base = 0)
- Function: explicit mpq_class::mpq_class (const string& s, int base = 0)
Construct an
mpq_classconverted from a string usingmpq_set_str(see Initializing Rationals).If the string is not a valid rational, an
std::invalid_argumentexception is thrown. The same applies tooperator=.
- Function: mpq_class operator"" _mpq (const char *str)
With C++11 compilers, integral rationals can be constructed with the syntax
123_mpqwhich is equivalent tompq_class(123_mpz). Other rationals can be built as-1_mpq/2or0xb_mpq/123456_mpz.
- Function: void mpq_class::canonicalize ()
Put an
mpq_classinto canonical form, as per Rational Number Functions. All arithmetic operators require their operands in canonical form, and will return results in canonical form.
- Function: mpq_class abs (mpq_class op)
- Function: int cmp (mpq_class op1, type op2)
- Function: int cmp (type op1, mpq_class op2)
- Function: double mpq_class::get_d (void)
- Function: string mpq_class::get_str (int base = 10)
- Function: int mpq_class::set_str (const char *str, int base)
- Function: int mpq_class::set_str (const string& str, int base)
- Function: int sgn (mpq_class op)
- Function: void mpq_class::swap (mpq_class& op)
- Function: void swap (mpq_class& op1, mpq_class& op2)
These functions provide a C++ class interface to the corresponding GMP C routines.
cmpcan be used with any of the classes or the standard C++ types, exceptlong longandlong double.
- Function: mpz_class& mpq_class::get_num ()
- Function: mpz_class& mpq_class::get_den ()
Get a reference to an
mpz_classwhich is the numerator or denominator of anmpq_class. This can be used both for read and write access. If the object returned is modified, it modifies the originalmpq_class.If direct manipulation might produce a non-canonical value, then
mpq_class::canonicalizemust be called before further operations.
- Function: mpz_t mpq_class::get_num_mpz_t ()
- Function: mpz_t mpq_class::get_den_mpz_t ()
Get a reference to the underlying
mpz_tnumerator or denominator of anmpq_class. This can be passed to C functions expecting anmpz_t. Any modifications made to thempz_twill modify the originalmpq_class.If direct manipulation might produce a non-canonical value, then
mpq_class::canonicalizemust be called before further operations.
- Function: istream& operator>> (istream& stream, mpq_class& rop);
Read rop from stream, using its
iosformatting settings, the same asmpq_t operator>>(see C++ Formatted Input).If the rop read might not be in canonical form then
mpq_class::canonicalizemust be called.
Next: C++ Interface Random Numbers, Previous: C++ Interface Rationals, Up: C++ Class Interface [Index]
12.4 C++ Interface Floats
When an expression requires the use of temporary intermediate mpf_class
values, like f=g*h+x*y, those temporaries will have the same precision
as the destination f. Explicit constructors can be used if this
doesn’t suit.
- Function: mpf_class::mpf_class (type op)
- Function: mpf_class::mpf_class (type op, mp_bitcnt_t prec)
Construct an
mpf_class. Any standard C++ type can be used, exceptlong longandlong double, and any of the GMP C++ classes can be used.If prec is given, the initial precision is that value, in bits. If prec is not given, then the initial precision is determined by the type of op given. An
mpz_class,mpq_class, or C++ builtin type will give the defaultmpfprecision (see Initializing Floats). Anmpf_classor expression will give the precision of that value. The precision of a binary expression is the higher of the two operands.mpf_class f(1.5); // default precision mpf_class f(1.5, 500); // 500 bits (at least) mpf_class f(x); // precision of x mpf_class f(abs(x)); // precision of x mpf_class f(-g, 1000); // 1000 bits (at least) mpf_class f(x+y); // greater of precisions of x and y
- Function: explicit mpf_class::mpf_class (const mpf_t f)
- Function: mpf_class::mpf_class (const mpf_t f, mp_bitcnt_t prec)
Construct an
mpf_classfrom anmpf_t. The value in f is copied into the newmpf_class, there won’t be any permanent association between it and f.If prec is given, the initial precision is that value, in bits. If prec is not given, then the initial precision is that of f.
- Function: explicit mpf_class::mpf_class (const char *s)
- Function: mpf_class::mpf_class (const char *s, mp_bitcnt_t prec, int base = 0)
- Function: explicit mpf_class::mpf_class (const string& s)
- Function: mpf_class::mpf_class (const string& s, mp_bitcnt_t prec, int base = 0)
Construct an
mpf_classconverted from a string usingmpf_set_str(see Assigning Floats). If prec is given, the initial precision is that value, in bits. If not, the defaultmpfprecision (see Initializing Floats) is used.If the string is not a valid float, an
std::invalid_argumentexception is thrown. The same applies tooperator=.
- Function: mpf_class operator"" _mpf (const char *str)
With C++11 compilers, floats can be constructed with the syntax
1.23e-1_mpfwhich is equivalent tompf_class("1.23e-1").
- Function: mpf_class& mpf_class::operator= (type op)
Convert and store the given op value to an
mpf_classobject. The same types are accepted as for the constructors above.Note that
operator=only stores a new value, it doesn’t copy or change the precision of the destination, instead the value is truncated if necessary. This is the same asmpf_setetc. Note in particular this means formpf_classa copy constructor is not the same as a default constructor plus assignment.mpf_class x (y); // x created with precision of y mpf_class x; // x created with default precision x = y; // value truncated to that precision
Applications using templated code may need to be careful about the assumptions the code makes in this area, when working with
mpf_classvalues of various different or non-default precisions. For instance implementations of the standardcomplextemplate have been seen in both styles above, though of coursecomplexis normally only actually specified for use with the builtin float types.
- Function: mpf_class abs (mpf_class op)
- Function: mpf_class ceil (mpf_class op)
- Function: int cmp (mpf_class op1, type op2)
- Function: int cmp (type op1, mpf_class op2)
- Function: bool mpf_class::fits_sint_p (void)
- Function: bool mpf_class::fits_slong_p (void)
- Function: bool mpf_class::fits_sshort_p (void)
- Function: bool mpf_class::fits_uint_p (void)
- Function: bool mpf_class::fits_ulong_p (void)
- Function: bool mpf_class::fits_ushort_p (void)
- Function: mpf_class floor (mpf_class op)
- Function: mpf_class hypot (mpf_class op1, mpf_class op2)
- Function: double mpf_class::get_d (void)
- Function: long mpf_class::get_si (void)
- Function: string mpf_class::get_str (mp_exp_t& exp, int base = 10, size_t digits = 0)
- Function: unsigned long mpf_class::get_ui (void)
- Function: int mpf_class::set_str (const char *str, int base)
- Function: int mpf_class::set_str (const string& str, int base)
- Function: int sgn (mpf_class op)
- Function: mpf_class sqrt (mpf_class op)
- Function: void mpf_class::swap (mpf_class& op)
- Function: void swap (mpf_class& op1, mpf_class& op2)
- Function: mpf_class trunc (mpf_class op)
These functions provide a C++ class interface to the corresponding GMP C routines.
cmpcan be used with any of the classes or the standard C++ types, exceptlong longandlong double.The accuracy provided by
hypotis not currently guaranteed.
- Function: mp_bitcnt_t mpf_class::get_prec ()
- Function: void mpf_class::set_prec (mp_bitcnt_t prec)
- Function: void mpf_class::set_prec_raw (mp_bitcnt_t prec)
Get or set the current precision of an
mpf_class.The restrictions described for
mpf_set_prec_raw(see Initializing Floats) apply tompf_class::set_prec_raw. Note in particular that thempf_classmust be restored to it’s allocated precision before being destroyed. This must be done by application code, there’s no automatic mechanism for it.
Next: C++ Interface Limitations, Previous: C++ Interface Floats, Up: C++ Class Interface [Index]
12.5 C++ Interface Random Numbers
- Class: gmp_randclass
The C++ class interface to the GMP random number functions uses
gmp_randclassto hold an algorithm selection and current state, as pergmp_randstate_t.
- Function: gmp_randclass::gmp_randclass (void (*randinit) (gmp_randstate_t, …), …)
Construct a
gmp_randclass, using a call to the given randinit function (see Random State Initialization). The arguments expected are the same as randinit, but withmpz_classinstead ofmpz_t. For example,gmp_randclass r1 (gmp_randinit_default); gmp_randclass r2 (gmp_randinit_lc_2exp_size, 32); gmp_randclass r3 (gmp_randinit_lc_2exp, a, c, m2exp); gmp_randclass r4 (gmp_randinit_mt);
gmp_randinit_lc_2exp_sizewill fail if the size requested is too big, anstd::length_errorexception is thrown in that case.
- Function: gmp_randclass::gmp_randclass (gmp_randalg_t alg, …)
Construct a
gmp_randclassusing the same parameters asgmp_randinit(see Random State Initialization). This function is obsolete and the above randinit style should be preferred.
- Function: void gmp_randclass::seed (unsigned long int s)
- Function: void gmp_randclass::seed (mpz_class s)
Seed a random number generator. See see Random Number Functions, for how to choose a good seed.
- Function: mpz_class gmp_randclass::get_z_bits (mp_bitcnt_t bits)
- Function: mpz_class gmp_randclass::get_z_bits (mpz_class bits)
Generate a random integer with a specified number of bits.
- Function: mpz_class gmp_randclass::get_z_range (mpz_class n)
Generate a random integer in the range 0 to n-1 inclusive.
- Function: mpf_class gmp_randclass::get_f ()
- Function: mpf_class gmp_randclass::get_f (mp_bitcnt_t prec)
Generate a random float f in the range 0 <= f < 1. f will be to prec bits precision, or if prec is not given then to the precision of the destination. For example,
gmp_randclass r; ... mpf_class f (0, 512); // 512 bits precision f = r.get_f(); // random number, 512 bits
Previous: C++ Interface Random Numbers, Up: C++ Class Interface [Index]
12.6 C++ Interface Limitations
mpq_classand Templated ReadingA generic piece of template code probably won’t know that
mpq_classrequires acanonicalizecall if inputs read withoperator>>might be non-canonical. This can lead to incorrect results.operator>>behaves as it does for reasons of efficiency. A canonicalize can be quite time consuming on large operands, and is best avoided if it’s not necessary.But this potential difficulty reduces the usefulness of
mpq_class. Perhaps a mechanism to telloperator>>what to do will be adopted in the future, maybe a preprocessor define, a global flag, or aniosflag pressed into service. Or maybe, at the risk of inconsistency, thempq_classoperator>>could canonicalize and leavempq_toperator>>not doing so, for use on those occasions when that’s acceptable. Send feedback or alternate ideas to gmp-bugs@gmplib.org.- Subclassing
Subclassing the GMP C++ classes works, but is not currently recommended.
Expressions involving subclasses resolve correctly (or seem to), but in normal C++ fashion the subclass doesn’t inherit constructors and assignments. There’s many of those in the GMP classes, and a good way to reestablish them in a subclass is not yet provided.
- Templated Expressions
A subtle difficulty exists when using expressions together with application-defined template functions. Consider the following, with
Tintended to be some numeric type,template <class T> T fun (const T &, const T &);
When used with, say, plain
mpz_classvariables, it works fine:Tis resolved asmpz_class.mpz_class f(1), g(2); fun (f, g); // Good
But when one of the arguments is an expression, it doesn’t work.
mpz_class f(1), g(2), h(3); fun (f, g+h); // Bad
This is because
g+hends up being a certain expression template type internal togmpxx.h, which the C++ template resolution rules are unable to automatically convert tompz_class. The workaround is simply to add an explicit cast.mpz_class f(1), g(2), h(3); fun (f, mpz_class(g+h)); // Good
Similarly, within
funit may be necessary to cast an expression to typeTwhen calling a templatedfun2.template <class T> void fun (T f, T g) { fun2 (f, f+g); // Bad } template <class T> void fun (T f, T g) { fun2 (f, T(f+g)); // Good }- C++11
C++11 provides several new ways in which types can be inferred:
auto,decltype, etc. While they can be very convenient, they don’t mix well with expression templates. In this example, the addition is performed twice, as if we had definedsumas a macro.mpz_class z = 33; auto sum = z + z; mpz_class prod = sum * sum;
This other example may crash, though some compilers might make it look like it is working, because the expression
z+zgoes out of scope before it is evaluated.mpz_class z = 33; auto sum = z + z + z; mpz_class prod = sum * 2;
It is thus strongly recommended to avoid
autoanywhere a GMP C++ expression may appear.
Previous: C++ Interface Random Numbers, Up: C++ Class Interface [Index]