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