suivant: Vigenere
monter: Corrigés des programmes
précédent: Changement de base
Table des matières
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;
}
suivant: Vigenere
monter: Corrigés des programmes
précédent: Changement de base
Table des matières
klaus
2010-08-05