next up previous contents
suivant: Vigenere monter: Corrigés des programmes précédent: Changement de base   Table des matières

Prise en main de GMP

introGMP.c


#include<stdio.h>
#include<gmp.h>

/*
  Affiche la table de multiplication de n, de 1 a to.
  n doit etre initialise.
 */

void afficheTableMultiplication(mpz_t n, long to)
{
  mpz_t res;
  if(to > 0)
    {
      afficheTableMultiplication(n, to - 1);
      mpz_init(res);
      mpz_mul_ui(res, n, to);
      mpz_out_str(NULL, 10, res);
      printf("\n");
    }
}


/*
  Place b^n dans res. res doit etre initialise
 */

void puissance(mpz_t b, mpz_t n, mpz_t res)
{
  mpz_t temp;
  if (!mpz_cmp_ui(n, 0))
    {
      mpz_set_ui(res, 1);
    }
  else
    {
      mpz_init(temp);
      if (mpz_divisible_ui_p(n, 2))
	{
	  mpz_t q;
	  mpz_t deux;
	  mpz_mul(temp, b, b);
	  mpz_init(q);
	  mpz_init_set_ui(deux, 2);
	  mpz_cdiv_q(q, n, deux);
	  puissance(temp, q, res);
	  mpz_clear(q);
	  mpz_clear(deux);
	}
      else
	{
	  mpz_t nMoinsUn;
	  mpz_init(nMoinsUn);
	  mpz_sub_ui(nMoinsUn, n, 1);
	  puissance(b, nMoinsUn, temp);
	  mpz_mul(res, temp, b);
	  mpz_clear(nMoinsUn);
	}
      mpz_clear(temp);
    }
}

/*
  Fonction d'Ackermann. res doit etre initialise. 
  Attention ! Ne doit etre utilise qu'avec des petites valeurs !
*/

void ackermann(mpz_t m, mpz_t n, mpz_t res)
{
  if(!mpz_cmp_ui(m, 0))
    {
      mpz_add_ui(res, n, 1);
    }
  else
    {
      mpz_t mMoinsUn;
      mpz_init(mMoinsUn);
      mpz_sub_ui(mMoinsUn, m, 1);
      if(!mpz_cmp_ui(n, 0))
	{
	  mpz_t un;
	  mpz_init_set_ui(un, 1);
	  ackermann(mMoinsUn, un, res);
	  mpz_clear(un);
	}
      else
	{
	  mpz_t nMoinsUn;
	  mpz_t appelRecursif;
	  mpz_init(nMoinsUn);
	  mpz_init(appelRecursif);
	  mpz_sub_ui(nMoinsUn, n, 1);
	  ackermann(m, nMoinsUn, appelRecursif);
	  ackermann(mMoinsUn, appelRecursif, res);
	  mpz_clear(appelRecursif); 
	  mpz_clear(nMoinsUn);
	}
      mpz_clear(mMoinsUn);
    }
}

/*
  Affiche toutes les images par la fonction d'Ackermann des couples 
  {(i, j) | 0 <= i <= m, 0 <= j <= n}
*/

void afficheAckermann(long m, long n)
{
  mpz_t i; 
  mpz_t j;
  mpz_t a;
  mpz_init(i);
  mpz_init(j);
  mpz_init(a);
  mpz_set_ui(i, 0);
  while(mpz_cmp_ui(i, m) <= 0)
    {
      mpz_set_ui(j, 0);
      while(mpz_cmp_ui(j, n) <= 0)
	{
	  printf("ackermann(");
	  mpz_out_str(NULL, 10, i);
	  printf(", ");
	  mpz_out_str(NULL, 10, j);
	  printf(")=");
	  ackermann(i, j, a);
	  mpz_out_str(NULL, 10, a);
	  printf("\n");
	  mpz_add_ui(j, j, 1);
	}
      mpz_add_ui(i, i, 1);
    }
}

int main()
{
  mpz_t v;
  mpz_t dix;
  mpz_t vingt;
  mpz_init(v);
  mpz_init_set_ui(dix, 10);
  mpz_init_set_ui(vingt, 20);
  puissance(dix, vingt, v);
  afficheTableMultiplication(v, 10);
  afficheAckermann(4, 15);
  return 0;
}


next up previous contents
suivant: Vigenere monter: Corrigés des programmes précédent: Changement de base   Table des matières
klaus 2010-08-05