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.
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
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,
mpz_t
mpz_class::get_mpz_t ()
¶mpq_t
mpq_class::get_mpq_t ()
¶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.
(type n)
¶Construct an mpz_class
. All the standard C++ types may be used, except
long long
and long double
, and all the GMP C++ classes can be
used, although conversions from mpq_class
and mpf_class
are
explicit
. Any necessary conversion follows the corresponding C
function, for example double
follows mpz_set_d
(see Assignment Functions).
explicit
mpz_class::mpz_class (const mpz_t z)
¶Construct an mpz_class
from an mpz_t
. The value in z is
copied into the new mpz_class
, there won’t be any permanent association
between it and z.
explicit
mpz_class::mpz_class (const char *s, int base = 0)
¶explicit
mpz_class::mpz_class (const string& s, int base = 0)
¶Construct an mpz_class
converted from a string using mpz_set_str
(see Assignment Functions).
If the string is not a valid integer, an std::invalid_argument
exception is thrown. The same applies to operator=
.
mpz_class
operator"" _mpz (const char *str)
¶With C++11 compilers, integers can be constructed with the syntax
123_mpz
which is equivalent to mpz_class("123")
.
mpz_class
operator/ (mpz_class a, mpz_class d)
¶mpz_class
operator% (mpz_class a, mpz_class d)
¶Divisions involving mpz_class
round towards zero, as per the
mpz_tdiv_q
and mpz_tdiv_r
functions (see Division Functions).
This is the same as the C99 /
and %
operators.
The mpz_fdiv…
or mpz_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());
mpz_class
abs (mpz_class op)
¶int
cmp (mpz_class op1, type op2)
¶int
cmp (type op1, mpz_class op2)
¶bool
mpz_class::fits_sint_p (void)
¶bool
mpz_class::fits_slong_p (void)
¶bool
mpz_class::fits_sshort_p (void)
¶bool
mpz_class::fits_uint_p (void)
¶bool
mpz_class::fits_ulong_p (void)
¶bool
mpz_class::fits_ushort_p (void)
¶double
mpz_class::get_d (void)
¶long
mpz_class::get_si (void)
¶string
mpz_class::get_str (int base = 10)
¶unsigned long
mpz_class::get_ui (void)
¶int
mpz_class::set_str (const char *str, int base)
¶int
mpz_class::set_str (const string& str, int base)
¶int
sgn (mpz_class op)
¶mpz_class
sqrt (mpz_class op)
¶mpz_class
gcd (mpz_class op1, mpz_class op2)
¶mpz_class
lcm (mpz_class op1, mpz_class op2)
¶mpz_class
mpz_class::factorial (type op)
¶mpz_class
factorial (mpz_class op)
¶mpz_class
mpz_class::primorial (type op)
¶mpz_class
primorial (mpz_class op)
¶mpz_class
mpz_class::fibonacci (type op)
¶mpz_class
fibonacci (mpz_class op)
¶void
mpz_class::swap (mpz_class& op)
¶void
swap (mpz_class& op1, mpz_class& op2)
¶These functions provide a C++ class interface to the corresponding GMP C
routines. Calling factorial
or primorial
on a negative number
is undefined.
cmp
can be used with any of the classes or the standard C++ types,
except long long
and long 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
.
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.
(type op)
¶(integer num, integer den)
¶Construct an mpq_class
. The initial value can be a single value of any
type (conversion from mpf_class
is explicit
), or a pair of
integers (mpz_class
or standard C++ integer types) representing a
fraction, except that long long
and long double
are not
supported. For example,
mpq_class q (99); mpq_class q (1.75); mpq_class q (1, 3);
explicit
mpq_class::mpq_class (const mpq_t q)
¶Construct an mpq_class
from an mpq_t
. The value in q is
copied into the new mpq_class
, there won’t be any permanent association
between it and q.
explicit
mpq_class::mpq_class (const char *s, int base = 0)
¶explicit
mpq_class::mpq_class (const string& s, int base = 0)
¶Construct an mpq_class
converted from a string using mpq_set_str
(see Initialization and Assignment Functions).
If the string is not a valid rational, an std::invalid_argument
exception is thrown. The same applies to operator=
.
mpq_class
operator"" _mpq (const char *str)
¶With C++11 compilers, integral rationals can be constructed with the syntax
123_mpq
which is equivalent to mpq_class(123_mpz)
. Other
rationals can be built as -1_mpq/2
or 0xb_mpq/123456_mpz
.
void
mpq_class::canonicalize ()
¶Put an mpq_class
into canonical form, as per Rational Number Functions. All arithmetic operators require their operands in canonical
form, and will return results in canonical form.
mpq_class
abs (mpq_class op)
¶int
cmp (mpq_class op1, type op2)
¶int
cmp (type op1, mpq_class op2)
¶double
mpq_class::get_d (void)
¶string
mpq_class::get_str (int base = 10)
¶int
mpq_class::set_str (const char *str, int base)
¶int
mpq_class::set_str (const string& str, int base)
¶int
sgn (mpq_class op)
¶void
mpq_class::swap (mpq_class& op)
¶void
swap (mpq_class& op1, mpq_class& op2)
¶These functions provide a C++ class interface to the corresponding GMP C routines.
cmp
can be used with any of the classes or the standard C++ types,
except long long
and long double
.
mpz_class&
mpq_class::get_num ()
¶mpz_class&
mpq_class::get_den ()
¶Get a reference to an mpz_class
which is the numerator or denominator
of an mpq_class
. This can be used both for read and write access. If
the object returned is modified, it modifies the original mpq_class
.
If direct manipulation might produce a non-canonical value, then
mpq_class::canonicalize
must be called before further operations.
mpz_t
mpq_class::get_num_mpz_t ()
¶mpz_t
mpq_class::get_den_mpz_t ()
¶Get a reference to the underlying mpz_t
numerator or denominator of an
mpq_class
. This can be passed to C functions expecting an
mpz_t
. Any modifications made to the mpz_t
will modify the
original mpq_class
.
If direct manipulation might produce a non-canonical value, then
mpq_class::canonicalize
must be called before further operations.
istream&
operator>> (istream& stream, mpq_class& rop);
¶Read rop from stream, using its ios
formatting settings,
the same as mpq_t operator>>
(see C++ Formatted Input).
If the rop read might not be in canonical form then
mpq_class::canonicalize
must be called.
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.
(type op)
¶(type op, mp_bitcnt_t prec)
¶Construct an mpf_class
. Any standard C++ type can be used, except
long long
and long 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 default mpf
precision (see Initialization Functions). An mpf_class
or 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
explicit
mpf_class::mpf_class (const mpf_t f)
¶(const mpf_t f, mp_bitcnt_t prec)
¶Construct an mpf_class
from an mpf_t
. The value in f is
copied into the new mpf_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.
explicit
mpf_class::mpf_class (const char *s)
¶(const char *s, mp_bitcnt_t prec, int base = 0)
¶explicit
mpf_class::mpf_class (const string& s)
¶(const string& s, mp_bitcnt_t prec, int base = 0)
¶Construct an mpf_class
converted from a string using mpf_set_str
(see Assignment Functions). If prec is given, the initial precision is
that value, in bits. If not, the default mpf
precision
(see Initialization Functions) is used.
If the string is not a valid float, an std::invalid_argument
exception
is thrown. The same applies to operator=
.
mpf_class
operator"" _mpf (const char *str)
¶With C++11 compilers, floats can be constructed with the syntax
1.23e-1_mpf
which is equivalent to mpf_class("1.23e-1")
.
mpf_class&
mpf_class::operator= (type op)
¶Convert and store the given op value to an mpf_class
object. 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 as mpf_set
etc. Note in particular this means for
mpf_class
a 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_class
values of
various different or non-default precisions. For instance implementations of
the standard complex
template have been seen in both styles above,
though of course complex
is normally only actually specified for use
with the builtin float types.
mpf_class
abs (mpf_class op)
¶mpf_class
ceil (mpf_class op)
¶int
cmp (mpf_class op1, type op2)
¶int
cmp (type op1, mpf_class op2)
¶bool
mpf_class::fits_sint_p (void)
¶bool
mpf_class::fits_slong_p (void)
¶bool
mpf_class::fits_sshort_p (void)
¶bool
mpf_class::fits_uint_p (void)
¶bool
mpf_class::fits_ulong_p (void)
¶bool
mpf_class::fits_ushort_p (void)
¶mpf_class
floor (mpf_class op)
¶mpf_class
hypot (mpf_class op1, mpf_class op2)
¶double
mpf_class::get_d (void)
¶long
mpf_class::get_si (void)
¶string
mpf_class::get_str (mp_exp_t& exp, int base = 10, size_t digits = 0)
¶unsigned long
mpf_class::get_ui (void)
¶int
mpf_class::set_str (const char *str, int base)
¶int
mpf_class::set_str (const string& str, int base)
¶int
sgn (mpf_class op)
¶mpf_class
sqrt (mpf_class op)
¶void
mpf_class::swap (mpf_class& op)
¶void
swap (mpf_class& op1, mpf_class& op2)
¶mpf_class
trunc (mpf_class op)
¶These functions provide a C++ class interface to the corresponding GMP C routines.
cmp
can be used with any of the classes or the standard C++ types,
except long long
and long double
.
The accuracy provided by hypot
is not currently guaranteed.
mp_bitcnt_t
mpf_class::get_prec ()
¶void
mpf_class::set_prec (mp_bitcnt_t prec)
¶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 Initialization Functions) apply to mpf_class::set_prec_raw
. Note in particular that the
mpf_class
must be restored to its allocated precision before being
destroyed. This must be done by application code, there’s no automatic
mechanism for it.
The C++ class interface to the GMP random number functions uses
gmp_randclass
to hold an algorithm selection and current state, as per
gmp_randstate_t
.
(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 with mpz_class
instead of mpz_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_size
will fail if the size requested is too big,
an std::length_error
exception is thrown in that case.
(gmp_randalg_t alg, …)
¶Construct a gmp_randclass
using the same parameters as
gmp_randinit
(see Random State Initialization). This function is
obsolete and the above randinit style should be preferred.
void
gmp_randclass::seed (unsigned long int s)
¶void
gmp_randclass::seed (mpz_class s)
¶Seed a random number generator. See see Random Number Functions, for how to choose a good seed.
mpz_class
gmp_randclass::get_z_bits (mp_bitcnt_t bits)
¶mpz_class
gmp_randclass::get_z_bits (mpz_class bits)
¶Generate a random integer with a specified number of bits.
mpz_class
gmp_randclass::get_z_range (mpz_class n)
¶Generate a random integer in the range 0 to n-1 inclusive.
mpf_class
gmp_randclass::get_f ()
¶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
mpq_class
and Templated ReadingA generic piece of template code probably won’t know that mpq_class
requires a canonicalize
call if inputs read with operator>>
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 tell operator>>
what to do will be adopted in
the future, maybe a preprocessor define, a global flag, or an ios
flag
pressed into service. Or maybe, at the risk of inconsistency, the
mpq_class
operator>>
could canonicalize and leave mpq_t
operator>>
not doing so, for use on those occasions when that’s
acceptable. Send feedback or alternate ideas to gmp-bugs@gmplib.org.
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.
A subtle difficulty exists when using expressions together with
application-defined template functions. Consider the following, with T
intended to be some numeric type,
template <class T> T fun (const T &, const T &);
When used with, say, plain mpz_class
variables, it works fine: T
is resolved as mpz_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+h
ends up being a certain expression template type
internal to gmpxx.h
, which the C++ template resolution rules are unable
to automatically convert to mpz_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 fun
it may be necessary to cast an expression to type
T
when calling a templated fun2
.
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 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 defined sum
as 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+z
goes 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 auto
anywhere a GMP C++
expression may appear.