## 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.

### 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.

### 12.2 C++ Interface Integers ¶

Function: mpz_class::mpz_class `(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).

Function: `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.

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_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=`.

Function: `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")`.

Function: `mpz_class` operator/ `(mpz_class a, mpz_class d)` ¶
Function: `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());

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 `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`.

### 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 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);

Function: `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.

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_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=`.

Function: `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`.

Function: `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.

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.

  `cmp` can be used with any of the classes or the standard C++ types, except `long long` and `long double`.

Function: `mpz_class&` mpq_class::get_num `()` ¶
Function: `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.

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_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.

Function: `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.

### 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, 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

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_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.

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_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=`.

Function: `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")`.

Function: `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.

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.

  `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.

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 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.

### 12.5 C++ Interface Random Numbers ¶

Class: gmp_randclass ¶

  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`.

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 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.

Function: gmp_randclass::gmp_randclass `(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.

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

### 12.6 C++ Interface Limitations ¶

`mpq_class` and Templated Reading

  A 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

  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 `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

  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.