Previous: , Up: Integer Functions   [Index]


5.16 Special Functions

The functions in this section are for various special purposes. Most applications will not need them.

Function: void mpz_array_init (mpz_t integer_array, size_t array_size, mp_size_t fixed_num_bits)

This is a special type of initialization. Fixed space of fixed_num_bits is allocated to each of the array_size integers in integer_array. There is no way to free the storage allocated by this function. Don’t call mpz_clear!

The integer_array parameter is the first mpz_t in the array. For example,

mpz_t  arr[20000];
mpz_array_init (arr[0], 20000, 512);

This function is only intended for programs that create a large number of integers and need to reduce memory usage by avoiding the overheads of allocating and reallocating lots of small blocks. In normal programs this function is not recommended.

The space allocated to each integer by this function will not be automatically increased, unlike the normal mpz_init, so an application must ensure it is sufficient for any value stored. The following space requirements apply to various routines,

  • mpz_abs, mpz_neg, mpz_set, mpz_set_si and mpz_set_ui need room for the value they store.
  • mpz_add, mpz_add_ui, mpz_sub and mpz_sub_ui need room for the larger of the two operands, plus an extra mp_bits_per_limb.
  • mpz_mul, mpz_mul_ui and mpz_mul_ui need room for the sum of the number of bits in their operands, but each rounded up to a multiple of mp_bits_per_limb.
  • mpz_swap can be used between two array variables, but not between an array and a normal variable.

For other functions, or if in doubt, the suggestion is to calculate in a regular mpz_init variable and copy the result to an array variable with mpz_set.

This function is obsolete. It will disappear from future MPIR releases.

Function: void * _mpz_realloc (mpz_t integer, mp_size_t new_alloc)

Change the space for integer to new_alloc limbs. The value in integer is preserved if it fits, or is set to 0 if not. The return value is not useful to applications and should be ignored.

mpz_realloc2 is the preferred way to accomplish allocation changes like this. mpz_realloc2 and _mpz_realloc are the same except that _mpz_realloc takes its size in limbs.

Function: mp_limb_t mpz_getlimbn (mpz_t op, mp_size_t n)

Return limb number n from op. The sign of op is ignored, just the absolute value is used. The least significant limb is number 0.

mpz_size can be used to find how many limbs make up op. mpz_getlimbn returns zero if n is outside the range 0 to mpz_size(op)-1.

Function: size_t mpz_size (mpz_t op)

Return the size of op measured in number of limbs. If op is zero, the returned value will be zero.

Function: const mp_limb_t * mpz_limbs_read (const mpz_t x)

Return a pointer to the limb array representing the absolute value of x. The size of the array is mpz_size(x). Intended for read access only.

Function: mp_limb_t * mpz_limbs_write (mpz_t x, mp_size_t n)
Function: mp_limb_t * mpz_limbs_modify (mpz_t x, mp_size_t n)

Return a pointer to the limb array, intended for write access. The array is reallocated as needed, to make room for n limbs. Requires n > 0. The mpz_limbs_modify function returns an array that holds the old absolute value of x, while mpz_limbs_write may destroy the old value and return an array with unspecified contents.

Function: void mpz_limbs_finish (mpz_t x, mp_size_t s)

Updates the internal size field of x. Used after writing to the limb array pointer returned by mpz_limbs_write or mpz_limbs_modify is completed. The array should contain abs(s) valid limbs, representing the new absolute value for x, and the sign of x is taken from the sign of s. This function never reallocates x, so the limb pointer remains valid.

void foo (mpz_t x)
{
  mp_size_t n, i;
  mp_limb_t *xp;

  n = mpz_size (x);
  xp = mpz_limbs_modify (x, 2*n);
  for (i = 0; i < n; i++)
    xp[n+i] = xp[n-1-i];
  mpz_limbs_finish (x, mpz_sgn (x) < 0 ? - 2*n : 2*n);
}
Function: mpz_srcptr mpz_roinit_n (mpz_t x, const mp_limb_t *xp, mp_size_t xs)

Special initialization of x, using the given limb array and size. x should be treated as read-only: it can be passed safely as input to any mpz function, but not as an output. The array xp must point to at least a readable limb, its size is abs(xs), and the sign of x is the sign of xs. For convenience, the function returns x, but cast to a const pointer type.

void foo (mpz_t x)
{
  static const mp_limb_t y[3] = { 0x1, 0x2, 0x3 };
  mpz_t tmp;
  mpz_add (x, x, mpz_roinit_n (tmp, y, 3));
}
Macro: mpz_t MPZ_ROINIT_N (mp_limb_t *xp, mp_size_t xs)

This macro expands to an initializer which can be assigned to an mpz_t variable. The limb array xp must point to at least a readable limb, moreover, unlike the mpz_roinit_n function, the array must be normalized: if xs is non-zero, then xp[abs(xs)-1] must be non-zero. Intended primarily for constant values. Using it for non-constant values requires a C compiler supporting C99.

void foo (mpz_t x)
{
  static const mp_limb_t ya[3] = { 0x1, 0x2, 0x3 };
  static const mpz_t y = MPZ_ROINIT_N ((mp_limb_t *) ya, 3);

  mpz_add (x, x, y);
}

Previous: Miscellaneous Functions, Up: Integer Functions   [Index]