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 ?

VOTRE RÉPONSE ICI

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 une précision absolue \(\eta\), c’est-à-dire la différence de valeur seuil en dessous de laquelle on considère que deux nombres sont égaux : \(x \approx 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 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 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’ordre de grandeur qui varie très vite : \(e^1 \simeq 10^0\), \(e^5 \simeq 10^2\), \(e^{10} \simeq 10^5\)

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ètre les nombres \(x\), \(y\) et \(\varepsilon\).

/** Valeur absolue pour type double
 * @param x un nombre de type double
 * @return la valeur absolue de x
**/
// VOTRE CODE ICI
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|
**/
// VOTRE CODE ICI
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 ?

VOTRE RÉPONSE ICI

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.