Go to the first, previous, next, last section, table of contents.


GMP Variable Conventions

As a general rule, all GMP functions expect output arguments before input arguments. This notation is based on an analogy with the assignment operator. (The BSD MP compatibility functions disobey this rule, having the output argument(s) last.)

GMP lets you use the same variable for both input and output in one call. For example, the main function for integer multiplication, mpz_mul, can be used to square x and put the result back in x with

mpz_mul (x, x, x);

Before you can assign to a GMP variable, you need to initialize it by calling one of the special initialization functions. When you're done with a variable, you need to clear it out, using one of the functions for that purpose. Which function to use depends on the type of variable. See the chapters on integer functions, rational number functions, and floating-point functions for details.

A variable should only be initialized once, or at least cleared out between each initialization. After a variable has been initialized, it may be assigned to any number of times.

For efficiency reasons, avoid initializing and clearing out a GMP variable in a loop. Instead, initialize it before entering the loop, and clear it out after the loop has exited.

GMP variables are small, containing only a couple of sizes, and pointers to allocated data. Once you have initialized a GMP variable, you don't need to worry about space allocation. All functions in GMP automatically allocate additional space when a variable does not already have enough. They do not, however, reduce the space when a smaller value is stored. Most of the time this policy is best, since it avoids frequent re-allocation.

When a variable of type mpz_t is used as a function parameter, it's effectively a call-by-reference, meaning anything the function does to it will be be done to the original in the caller. When a function is going to return an mpz_t result, it should provide a separate parameter or parameters that it sets, like the GMP library functions do. A return of an mpz_t doesn't return the object, only a pointer to it, and this is almost certainly not what you want. All this applies to mpq_t and mpf_t too.

Here's an example function accepting an mpz_t parameter, doing a certain calculation, and returning a result.

void
myfunction (mpz_t result, mpz_t param, unsigned long n)
{
  unsigned long  i;
  
  mpz_mul_ui (result, param, n);
  for (i = 1; i < n; i++)
    mpz_add_ui (result, result, i*7);
}

int
main (void)
{
  mpz_t  r, n;
  mpz_init (r);
  mpz_init_set_str (n, "123456", 0);

  myfunction (r, n, 20L);
  mpz_out_str (stdout, 10, r); printf ("\n");

  return 0;
}

This example will work if result and param are the same variable, just like the library functions. But sometimes this is tricky to arrange, and an application might not want to bother for its own subroutines.

mpz_t is actually implemented as a one-element array of a certain structure type. This is why using it to declare a variable gives an object with the fields GMP needs, but then using it as a parameter passes a pointer to the object. Note that the actual contents of an mpz_t are for internal use only and you should not access them directly if you want your code to be compatible with future GMP releases.


Go to the first, previous, next, last section, table of contents.