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
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 :
Exercice 2
Implantez les deux fonctions suivantes dont on vous donne la documentation :
abs
qui prend cette fois en paramètre undouble
et retourne undouble
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 :
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
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)
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)
Trouvez des valeurs de
epsilon
telles que les nombres ci-dessous soient considérés comme égaux paregal_relatif
:
egal_relatif(15, 16, 0.001)
egal_relatif(0.0001, 0.002, 0.001)
Exercice 3 (suite)
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 toujoursfalse
. 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.