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

Partie 3 : comparaison de nombres flottants et précision absolue et relative#

Nous avons vus que les nombres flottants (float ou double) n’étaient qu’une approximation des nombres réels. Notamment, l’opérateur == diffère de l’égalité des nombres réels du fait des erreurs d’arrondis :

1.0 + 1e20 - 1e20 == 1e20 - 1e20 + 1.0

Exercice 1

  1. Exécutez les cinq cellules suivantes. Que constatez-vous ?

BEGIN SOLUTION

a et b ont bien des valeurs différentes mais s’affichent de la même manière.

END SOLUTION

double a,b;
a = 16;
b = 15.99999999999;
a
b
(a == b)

Précision absolue#

Définition : précision absolue

Chaque fois que l’on veut comparer deux nombres flottants, il faut spécifier avec quelle précision on veut les comparer.

Pour cela, on fixe un seuil de précision absolue \(\eta>0\) et on considère que deux nombres \(x\) et \(y\) sont égaux à \(\eta\) près si :

\[ |x - y| < \eta .\]

Exercice 2

Implantez les deux fonctions suivantes dont on vous donne la documentation :

  • abs qui prend cette fois en paramètre un double et retourne un double

  • egal qui prend en paramètres les nombres \(x\), \(y\) et \(\varepsilon\).

/** Valeur absolue pour type double
 * @param x un nombre de type double
 * @return la valeur absolue de x
**/
/// BEGIN SOLUTION
double abs(double x) {
    if (x < 0) {
        return -x;
    } else {
        return x;
    }
}
/// END SOLUTION
abs(-1.5)
CHECK( abs(-1.5) == 1.5 );
CHECK( abs( 2.2) == 2.2 );
/** Égalité entre deux flottants avec précision absolue
 * @param x un nombre de type double
 * @param y un nombre de type double
 * @param epsilon un nombre de type double
 * @return true si la valeur absolue de x - y est plus petite que epsilon
**/
/// BEGIN SOLUTION
bool egal(double x, double y, double epsilon) {
    return abs(x-y) < epsilon;
}
/// END SOLUTION
egal(1, 1.05, 0.01)
CHECK(     egal( 1,  1.05, 0.1 ) );
CHECK( not egal( 1,  1.05, 0.01) );
CHECK(     egal(10, 10.05, 0.1 ) );
CHECK( not egal(10, 10.05, 0.01) );

Précision relative ♣#

Indication

Si la notion de précision relative décrite ci-dessous ne vous paraît pas claire en première lecture, vous pouvez passer directement à la partie 4 et revenir ici ultérieurement.

Lorsque les valeurs à comparer sont très variables en ordre de grandeur, la précision absolue n’est souvent pas bien adaptée. Par exemple, si l’on compare des altitudes de pics montagneux, une précision absolue de l’ordre du mètre (\(\eta = 10^1\)m) suffit souvent. En revanche si l’on compare des tailles de personnes, on cherche généralement à précis au centimètre (\(\eta = 10^{-2}\)m).

Ainsi, dans les applications, c’est le plus souvent le nombre de chiffres significatifs en commun qui est pertinent à mesurer, ce que l’on formalise comme suit

Définition: précision relative

Pour comparer \(x\) et \(y\) avec une précision relative de l’ordre de cinq chiffres significatifs, on prend \(\varepsilon=10^{-5}=0,00001\), et on dit que \(x\) est égal à \(y\) à \(\varepsilon\) près si :

\[ |x - y| < \varepsilon|x| \qquad \text{et} \qquad |x - y| < \varepsilon |y|\]

Moralement : la différence entre \(x\) et \(y\) est négligeable devant \(x\) et devant \(y\).

Ce concept est particulièrement pertinent pour le calcul de l’exponentielle car celle-ci donne des valeurs d’ordres de grandeur très différents : \(e^1 \simeq 10^0\), \(e^5 \simeq 10^2\), \(e^{10} \simeq 10^5\)

Exercice 3

  1. Dans chacun des exemples suivants, est-ce que \(x\simeq y\) avec une précision relative \(\varepsilon=0.1\)? Une précision relative \(\varepsilon=0.01\)?

    • \(x=1.22\), \(y=1.24\)

    • \(x=1220\), \(y=1240\)

    • \(x=0.0122\), \(y=0.0124\)

    • \(x=0\), \(y=0.01\)

Exercice 3 (suite)

  1. Définissez la fonction suivante

/** Égalité entre deux flottants avec précision relative
 * @param x un nombre de type double
 * @param y un nombre de type double
 * @param epsilon un nombre de type double
 * @return true si la valeur absolue de x - y est plus petite que epsilon * |x| et que epsilon * |y|
**/
/// BEGIN SOLUTION
bool egal_relatif(double x, double y, double epsilon) {
    double distance = abs(x-y);
    return ((distance < epsilon * abs(x)) and (distance < epsilon * abs(y)));
}
/// END SOLUTION
egal_relatif(15.999999, 16, 0.00001)
CHECK(     egal_relatif( 1,  1.05, 0.1  ) );
CHECK( not egal_relatif( 1,  1.05, 0.01 ) );
CHECK(     egal_relatif(10, 10.05, 0.01) );
CHECK( not egal_relatif(10, 10.05, 0.001 ) );

Exercice 3 (suite)

  1. Trouvez des valeurs de epsilon telles que les nombres ci-dessous soient considérés comme égaux par egal_relatif :

egal_relatif(15, 16, 0.001)
egal_relatif(0.0001, 0.002, 0.001)

Exercice 3 (suite)

  1. Que se passe-t-il lorsque \(x\) ou \(y\) valent \(0\) ?

    BEGIN SOLUTION

    Lorsque \(x\) ou \(y\) valent \(0\) (même lorsque les deux valent \(0\)), la fonction egal_relatif retourne toujours false. On ne peut pas parler de précision relative à zéro.

    END SOLUTION

egal_relatif(0.00001, 0, 0.0000001)

Bilan de la partie 3#

Maintenant que avez défini la comparaison de nombres flottants avec une précision relative fixée, vous pouvez passer à la partie 4.