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

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

Sur les nombres flottants (float ou double) l’opérateur == n’est pas toujours très fiable à cause des erreurs d’arrondis :

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

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

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

Définition : précision relative#

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

Le plus simple est de fixer un seuil de précision absolue \(\eta\), c’est-à-dire la différence de valeur en dessous de laquelle on considère que deux nombres sont égaux : \(x \simeq y\) si \(|x - y| < \eta\).

Cependant, cette valeur de précision absolue peut être difficile à fixer, surtout quand les valeurs sont très variables en ordre de grandeur. Par exemple, si l’on considère des hauteurs de pics montagneux, on pourrait largement se satisfaire d’être précis à la dizaine de mètres (\(\eta = 10^1\)m) près. En revanche si l’on compare des tailles de personnes, on aimerait pouvoir être précis au centimètre (\(\eta = 10^{-2}\)m). On aurait donc besoin de précisions absolues totalement différentes selon l’ordre de grandeur des valeurs.

En fait c’est le plus souvent le nombre de chiffres significatifs en commun qui est pertinent à mesurer. Formellement, on utilise alors une précision relative. Si on veut comparer \(x\) et \(y\) avec une précision relative de l’ordre de cinq chiffres significatifs, on prendra \(\varepsilon=10^{-5}=0,00001\), et on dira 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 dans notre cas, car l’exponentielle 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

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\)

Implantation#

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

  • abs mais 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
**/
// REMPLACER CETTE LIGNE PAR VOTRE RÉPONSE
abs(-1.5)
CHECK( abs(-1.5) == 1.5 );
CHECK( abs( 2.2) == 2.2 );
/** É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|
**/
// REMPLACER CETTE LIGNE PAR VOTRE RÉPONSE
egal(15.999999, 16, 0.00001)
CHECK( egal(15.999999, 16, 0.00001) == true  );
CHECK( egal(15.99, 16, 0.00001)     == false );

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

egal(15, 16, 0.001)
egal(0.0001, 0.002, 0.00001)

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

egal(0.00001, 0, 0.0000001)

Bilan de la partie 3#

Maintenant que la notion de précision relative est bien définie, et que vous avez implanté la comparaison de nombres flottants avec une précision relative fixée, vous pouvez passer à la partie 4.