Adloun

L'exponentiation rapide, prouvée et comptée

Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 3 — Algorithmes, programmes et complexité

Énoncé

Écrire une fonction qui calcule en multiplications. Donner spécification, variant, invariant et complexité, puis compter les multiplications effectuées.

Corrigé


/* Renvoie x elevee a la puissance n.
   Precondition  : n >= 0.
   Postcondition : le resultat vaut x^n, au debordement des long pres. */
long puissance(long x, int n) {
    assert(n >= 0);
    long r = 1, b = x;
    int e = n;
    /* INVARIANT : r * b^e == x^n, et e >= 0.     VARIANT : e. */
    while (e > 0) {
        if (e % 2 == 1) { r = r * b; }
        b = b * b;
        e = e / 2;
    }
    return r;
}

Terminaison. Variant : entier, positif tant que la condition tient, et divisé par deux à chaque tour, donc strictement décroissant dès que . La boucle fait exactement tours pour .

Correction. Initialisation : , , , donc . Conservation : soit en début de tour.

Utilisation : à la sortie, , donc et l'invariant devient . C'est la postcondition.

Complexité, exactement. Le tour d'indice fait une élévation au carré, plus une multiplication si le bit de vaut . Le nombre total de multiplications est donc

où est le nombre de dans l'écriture binaire de . La mesure confirme la formule à l'unité près :


       n | binaire        | rapide | naive
       1 | 1              |      2 |       1
       7 | 111            |      6 |       7
       8 | 1000           |      5 |       8
      15 | 1111           |      8 |      15
      16 | 10000          |      6 |      16
     100 | 1100100        |     10 |     100
    1000 | 1111101000     |     16 |    1000
 1000000 | (20 bits, 7 a 1)|    27 | 1000000

Pour : 27 multiplications au lieu d'un million.

iRemarqueDeux détails d'honnêteté

Le tableau montre que pour la version rapide fait multiplications et la naïve : le dernier tour élève au carré pour rien. On peut l'économiser en testant avant l'élévation ; le gain est d'une multiplication, et le code devient moins symétrique. Ensuite, le résultat déborde très vite : ne tient dans aucun long. La fonction reste utile telle quelle pour l'exponentiation modulaire, où l'on réduit à chaque tour — c'est ainsi qu'elle sert en cryptographie.

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.