TP : implanter la fonction exponentielle (1/5)#

Imaginez que vous développez la nouvelle librairie de fonctions mathématiques du C++. Au départ, les seules opérations auxquelles vous avez le droit sont les opérations arithmétiques usuelles telles que + * / %. Notre but aujourd’hui est d’écrire la fonction qui calcule \(e^x\).

Pour cela, on utilise la définition de \(e^x\) en tant que série (somme infinie) :

\[e^x = \sum_{n=0}^{+\infty} \frac{x^n}{n!} = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} +\cdots+\frac{x^n}{n!}+\cdots\]

On remarque que l’on a besoin en particulier de calculer \(x^n\) ainsi que \(n!\). Ce sera l’objet de la première partie. Dans la deuxième partie, on calculera une approximation de la fonction exponentielle en la tronquant à un nombre fixé de termes; par exemple : \(e^x \simeq 1+\frac{x^2}{2!}+\frac{x^3}{3!}\)

La précision d’une telle approximation dépend beaucoup de la valeur de \(x\). Dans la partie 4 on utilisera une méthode adaptative : on fixera cette fois la précision relative souhaitée et on calculera autant de termes que nécessaire pour atteindre cette précision. Pour cela on aura préalablement défini – et implanté ! – dans la partie 3 ce que l’on entend par précision relative.

Partie 1 : fonctions puissance et factorielle#

Le but de cette partie est d’écrire les fonctions factorielle et puissance (vues en TD) et de vérifier que l’on obtient bien les résultats attendus. Complétez la fonction factorielle ci-dessous puis vérifiez les résultats des cellules suivantes :

/** Factorielle
 * @param n un entier positif ou nul
 * @return la valeur n! en tant que double
**/
double factorielle(int n) {
    /// BEGIN SOLUTION
    double r = 1;
    for (int i = 1; i <= n; i++) {
        r *= i;
    }
    return r;
    /// END SOLUTION
}
factorielle(5)
CHECK( factorielle(0) == 1   );   // Par convention mathématique
CHECK( factorielle(3) == 6   );
CHECK( factorielle(4) == 24  );
CHECK( factorielle(5) == 120 );
// BEGIN HIDDEN TESTS
CHECK( factorielle(8) == 40320);
// END HIDDEN TESTS

Vérifiez l’ordre de grandeur du calcul suivant. Si la valeur est aberrante, vérifiez l’utilisation du type double à toutes les étapes du calcul.

factorielle(100)

Complétez la fonction puissance ci-dessous puis vérifiez les résultats des cellules suivantes :

/** Puissance
 * @param x un nombre de type double
 * @param n un entier positif ou nul
 * @return le nombre x^n de type double
**/
double puissance(double x, int n) {
    /// BEGIN SOLUTION
    double r = 1;
    for(int i = 0; i < n; i++) {
        r *= x;
    }
    return r;
    /// END SOLUTION
}
puissance(2, 4)
CHECK( puissance(1,  10) == 1     );
CHECK( puissance(2,   5) == 32    );
CHECK( puissance(1.5, 3) == 3.375 );

Ajoutez des tests (toujours avec CHECK) pour vérifier les cas limites : vérifiez (pour une valeur de \(x\) de votre choix) que \(x^0\) vaut \(1\), que \(0^r\) vaut \(0\) pour \(r\) non nul, et que \(0^0\) vaut \(1\) :

/// BEGIN SOLUTION
CHECK( puissance(3, 0) == 1 );
CHECK( puissance(0, 3) == 0 );
CHECK( puissance(0, 0) == 1 );
/// END SOLUTION

Bilan de la partie 1#

Vous avez maintenant les prérequis pour implanter la fonction exponentielle. Vous pouvez maintenant passer à la partie 2.