Erreurs dans les opérations flottantes

Avec la leçon précédente, nous savons maintenant que seul un sous-ensemble fini des réels peut être stocké exactement et nous connaissons la structure IEEE 754. Cette leçon explore les conséquences pratiques de cette limitation : comment les erreurs apparaissent lors des calculs et comment elles se propagent à travers les opérations arithmétiques.

Troncature versus arrondissement

Lorsqu'un nombre réel possède plus de chiffres significatifs que le système ne peut en stocker, il faut le projeter sur l'ensemble des nombres machine. Deux stratégies principales existent.

Notation

Soit un système flottant avec :

  • : la base
  • : le nombre de chiffres significatifs (précision)
  • : les bornes de l'exposant

Tout nombre réel peut s'écrire en notation flottante normalisée :

On note la représentation flottante de dans le système.

Troncature (arrondi vers zéro)

La troncature consiste à ignorer les chiffres au-delà de la position . C'est équivalent à un arrondi vers zéro.

Définition formelle : Soit . La troncature est :

Borne d'erreur absolue : L'erreur de troncature est bornée par :

Borne d'erreur relative : Pour :

Cette borne est l'epsilon machine .

💡

Lien avec IEEE 754

Pour IEEE 754 en base :

  • Simple précision : bits (23 stockés + 1 implicite), donc
  • Double précision : bits (52 stockés + 1 implicite), donc

Démonstration appliquée : troncature

Exemple 1 : Tronquer dans un système .

Étape 1 : Écrire en notation flottante normalisée.

Étape 2 : Identifier les chiffres de la mantisse.

Étape 3 : Conserver uniquement les premiers chiffres.

Étape 4 : Calculer l'erreur et vérifier la borne.

Vérifions la borne : . Notre erreur de 0,566% est bien inférieure.

Exemple 2 : Tronquer dans un système .

Étape 1 : Normaliser.

Étape 2 : Identifier les chiffres.

Étape 3 : Tronquer à chiffres.

Étape 4 : Calculer l'erreur.

Propriété fondamentale : La troncature est biaisée puisque :

En d'autres termes, la troncature rapproche toujours vers zéro.

Arrondissement au plus proche (round to nearest)

L'arrondissement au plus proche projette un nombre réel sur le nombre machine le plus proche, minimisant ainsi l'erreur.

Définition formelle : Soit un réel et les deux nombres machine encadrant (avec ). L'arrondi au plus proche est :

Borne d'erreur relative : Pour l'arrondissement au plus proche :

est l'epsilon machine. Cette borne est deux fois plus petite que pour la troncature.

Procédure pratique (ajout de demi-unité) :

Soit en notation normalisée (avec ).

Méthode 1 — Sur la mantisse : Ajouter à la mantisse, puis tronquer :

Méthode 2 — Sur le nombre : Ajouter au nombre, puis tronquer :

💡

Comprendre la demi-unité

D'où vient la formule ?

Dans un système , les nombres machine avec exposant ont la forme .

Deux nombres machine consécutifs (même exposant) diffèrent d'une unité au -ème chiffre de la mantisse. Ce chiffre est à la position après la virgule, c'est-à-dire :

Par exemple, pour : le 3ème chiffre est à la position .

L'écart entre mantisses est donc , et l'écart entre les nombres (en multipliant par ) est :

Pour arrondir au plus proche, on ajoute la moitié de cet écart :

Exemple numérique : Pour avec :

  • Exposant :
  • Les mantisses voisines (à chiffres) sont et
  • Le 3ème chiffre est à la position , donc l'écart entre mantisses est
  • Écart entre nombres machine :
  • Demi-unité :

Note sur les conventions : Certains ouvrages utilisent une convention différente où la mantisse est de la forme avec . Dans ce cas, l'exposant est décalé de 1, et la formule devient . Le résultat final est le même.

Démonstration appliquée : arrondissement

Exemple 1 : Arrondir dans un système .

Étape 1 : Normaliser.

Étape 2 : Identifier les nombres machine encadrants.

Avec chiffres significatifs, les nombres machine autour de 1237 sont :

L'écart entre eux est , donc la demi-unité est .

Étape 3 : Appliquer la méthode d'ajout de demi-unité.

Étape 4 : Tronquer.

Vérification : 1237 est à distance 7 de 1230 et à distance 3 de 1240. Le plus proche est bien 1240. ✓

Étape 5 : Calculer l'erreur et vérifier la borne.

Vérifions la borne : . Notre erreur de 0,243% est bien inférieure. ✓

Exemple 2 : Arrondir dans un système .

Étape 1 : Normaliser.

Les nombres machine encadrants sont toujours 1230 et 1240.

Étape 2 : Ajouter la demi-unité (5).

Étape 3 : Tronquer.

Vérification : 1234 est à distance 4 de 1230 et à distance 6 de 1240. Le plus proche est bien 1230. ✓

Étape 4 : L'erreur est de 4, soit (toujours sous la borne de 0,5%).

Comparaison des méthodes

Nombre xTroncatureErreurArrondissementErreur

Observations :

  • La troncature produit toujours une erreur de même signe que (vers zéro)
  • L'arrondissement produit des erreurs positives ou négatives selon le cas
  • L'erreur maximale par arrondissement est environ la moitié de celle par troncature

Récapitulatif des bornes d'erreur

MéthodeBorne d'erreur relativePropriété
TroncatureBiaisée (vers zéro)
Arrondi au plus procheNon biaisée

En pratique : les modes d'arrondi IEEE 754

Tous les processeurs modernes implémentent la norme IEEE 754. Cette norme définit 5 modes d'arrondi :

ModeDescriptionUsage
Round to nearest, ties to evenArrondi au plus proche, égalité → pairDéfaut
Round to nearest, ties awayArrondi au plus proche, égalité → loin de 0Rare
Round toward Arrondi vers le hautArithmétique d'intervalles
Round toward Arrondi vers le basArithmétique d'intervalles
Round toward 0TroncatureConversion float → entier
💡

Règle du pair (ties to even)

Quand un nombre est exactement au milieu de deux nombres machine, IEEE 754 arrondit vers celui dont le dernier bit est pair. Cette règle élimine un biais subtil qui apparaîtrait si on arrondissait toujours vers le haut en cas d'égalité.

Exemple : 1,5 est au milieu de 1 et 2 → on arrondit à 2 (pair). Mais 2,5 au milieu de 2 et 3 → on arrondit aussi à 2 (pair).

Le mode par défaut est l'arrondi au plus proche (« round to nearest, ties to even »). C'est ce qu'utilisent votre ordinateur, votre téléphone, et pratiquement tout appareil numérique pour les opérations flottantes.

Pourquoi l'arrondi par défaut et pas la troncature ? La troncature introduit un biais systématique : les résultats sont toujours décalés vers zéro. Sur des millions d'opérations, ce biais s'accumule et fausse les résultats. L'arrondi au plus proche n'a pas ce biais — les erreurs positives et négatives se compensent statistiquement.

Quand la troncature est-elle utilisée ? La troncature (« round toward 0 ») n'est pas utilisée pour les opérations flottantes standard, mais elle intervient généralement dans deux cas :

  • Conversion float → entier : int(3.7) en Python ou (int)3.7 en C donne 3. La partie fractionnaire est supprimée.
  • Mode explicitement activé : le programmeur peut changer le mode d'arrondi pour des besoins spécifiques (arithmétique d'intervalles, etc.).

Comportement des quatre opérations

En arithmétique flottante, les opérations classiques ne donnent généralement pas le résultat mathématiquement exact. La norme IEEE 754 exige cependant que chaque opération soit correctement arrondie : le résultat doit être celui qu'on obtiendrait en calculant avec une précision infinie, puis en arrondissant.

Notation et modèle d'erreur

Soit une opération arithmétique. On note :

  • : le résultat exact (réel)
  • : le résultat flottant calculé

Modèle standard (IEEE 754) : Pour toute opération entre deux nombres flottants et :

est l'epsilon machine.

💡

Comment lire cette formule ?

Cette formule exprime que le résultat flottant est légèrement perturbé par rapport au résultat exact :

  • est le résultat mathématiquement exact (ce qu'on obtiendrait avec une précision infinie)
  • est le résultat stocké par l'ordinateur (arrondi)
  • est la petite erreur relative introduite par l'arrondi

Multiplier par revient à dire que le résultat est décalé d'un facteur proportionnel à lui-même. Par exemple, si et le résultat exact est 3,14159, alors le résultat flottant sera environ .

L'erreur absolue est petite, mais l'erreur relative (le rapport erreur/valeur) est toujours bornée par .

Bornes d'erreur par opération

OpérationNotationBorne d'erreur relative
Addition
Soustraction
Multiplication
Division

Les symboles représentent les opérations flottantes (calculées), par opposition aux opérations exactes .

⚠️

Attention : erreurs d'entrée

Si les opérandes et sont eux-mêmes des approximations de valeurs réelles et , l'erreur totale combine l'erreur d'arrondi de l'opération et les erreurs déjà présentes dans les opérandes.

Démonstration appliquée : Addition

Calculons dans un système .

Étape 1 : Représenter les opérandes en notation flottante normalisée

Étape 2 : Aligner les exposants

Pour additionner, on exprime les deux nombres avec le même exposant (le plus grand) :

Étape 3 : Effectuer l'addition exacte

Étape 4 : Arrondir à chiffres

Le résultat exact doit être arrondi. En notation normalisée : .

Par troncature :

Par arrondissement (demi-unité = 0,005) :

Bilan et vérification du modèle :

  • Valeur exacte :
  • Par arrondissement :
  • Erreur relative :
  • Borne théorique :

L'erreur respecte bien la borne du modèle IEEE 754.

Démonstration appliquée : Multiplication

Calculons dans un système .

Étape 1 : Représenter les opérandes

Note : n'est pas représentable exactement ; on a déjà une erreur d'entrée.

Étape 2 : Multiplier les mantisses

Étape 3 : Additionner les exposants

Résultat intermédiaire :

Étape 4 : Normaliser et arrondir

Le résultat est déjà normalisé et a exactement 3 chiffres. Pas d'arrondi supplémentaire.

Bilan : Le résultat mathématique devrait être , mais l'arithmétique flottante donne . L'erreur provient de la représentation initiale de , pas de l'opération de multiplication elle-même.

💡

Erreur d'entrée vs erreur d'opération

Cet exemple illustre la différence entre :

  • L'erreur d'arrondi de l'opération (bornée par )
  • L'erreur d'entrée (ici, n'est pas représentable exactement)

L'erreur totale peut excéder à cause des erreurs d'entrée.

Perte de précision

Certaines configurations de calcul amplifient dramatiquement les erreurs.

Le phénomène d'absorption

L'epsilon machine explique pourquoi certains calculs semblent « ignorer » de petites quantités :

absorption.pypython
# Phénomène d'absorption
grand = 1e16
petit = 1.0

resultat = grand + petit - grand
print(f"(1e16 + 1) - 1e16 = {resultat}")  # Devrait être 1, mais...

# Explication : 1.0 est trop petit par rapport à 1e16
# pour affecter sa représentation flottante
print(f"1e16 + 1 == 1e16 : {1e16 + 1 == 1e16}")

Ce phénomène s'appelle l'absorption : un petit nombre ajouté à un grand nombre peut être « absorbé » sans modifier le résultat.

Démonstration appliquée : Absorption

Calculons dans un système .

Étape 1 : Représenter les opérandes en notation normalisée

Étape 2 : Aligner les exposants

Pour soustraire, on exprime avec l'exposant de :

Étape 3 : Effectuer la soustraction exacte

Résultat exact :

Étape 4 : Arrondir à chiffres

Par troncature :

Par arrondissement :

Observation : Par arrondissement, le résultat est identique à l'opérande initial ! Le petit nombre a été complètement « absorbé ». C'est un cas typique où alors que .

Perte d'associativité

En mathématiques, l'addition est associative :

En arithmétique flottante, cette propriété n'est plus garantie.

associativite.pypython
# Démonstration de la perte d'associativité
a = 1e16
b = -1e16
c = 1.0

# Ordre 1 : (a + b) + c
resultat1 = (a + b) + c
print(f"(1e16 + (-1e16)) + 1 = {resultat1}")

# Ordre 2 : a + (b + c)
resultat2 = a + (b + c)
print(f"1e16 + ((-1e16) + 1) = {resultat2}")

print(f"Les résultats sont égaux : {resultat1 == resultat2}")

Dans le premier cas, exactement, puis .

Dans le second cas, (le 1 est absorbé), puis .

🚨

Règle critique

L'ordre des opérations affecte le résultat en arithmétique flottante. Pour maximiser la précision, il est généralement préférable d'additionner d'abord les termes de même ordre de grandeur, en commençant par les plus petits.

Perte de commutativité de la multiplication

La multiplication aussi peut perdre sa commutativité dans des cas extrêmes :

commutativite.pypython
# Note sur les exposants en Python (double précision IEEE 754):
# - Exposant min (min_exp): -1021 (en base 2), soit environ 10^-307 (min_10_exp)
# - Exposant max (max_exp): 1024 (en base 2), soit environ 10^308 (max_10_exp)
# Le biais est de 1023, donc l'exposant réel va de -1022 à +1023 pour les nombres normalisés.
# Pour voir toutes les infos: import sys; print(sys.float_info)

# La multiplication reste généralement commutative,
# mais l'ordre peut affecter les résultats intermédiaires

a = 1e-307
b = 1e308  ## essayer aussi avec 1e306, 1e307, 1e308, 1e309
c = 2.0

# Ordre 1
r1 = (a * b) * c
print(f"({a} * {b}) * {c} = {r1}")

# Ordre 2 : risque de dépassement intermédiaire
r2 = (b * c) * a
print(f"({b} * {c}) * {a} = {r2}")

# Ordre 3 : risque de soupassement intermédiaire
r3 = (a * c) * b
print(f"({a} * {c}) * {b} = {r3}")

Résultats intermédiaires

Pour toute suite d'opérations, chaque résultat intermédiaire est arrondi (ou tronqué) avant d'être utilisé dans l'opération suivante. Les erreurs s'accumulent donc à chaque étape.

Résumé des pièges courants

PiègeCauseConséquence
AbsorptionAddition de nombres d'ordres très différentsLe petit nombre est « ignoré »
Perte d'associativitéOrdres de grandeur variésRésultat dépend de l'ordre des opérations
Accumulation d'erreursLongues chaînes de calculsErreur finale peut être très grande
Dépassement/soupassementRésultats hors plageInf, 0 ou NaN
⚠️

Annulation catastrophique

Un piège particulièrement dangereux est l'annulation catastrophique : la soustraction de deux nombres très proches provoque une perte massive de chiffres significatifs. Ce phénomène est si important qu'il fait l'objet d'une leçon dédiée.

Ce qu'il faut retenir

L'arithmétique flottante n'est pas l'arithmétique des réels. Les propriétés mathématiques fondamentales (associativité, distributivité) ne sont plus garanties. Les phénomènes d'absorption et de décalage peuvent causer des pertes de précision significatives.

Formules essentielles

Bornes d'erreur pour la représentation :

Modèle standard pour les opérations (IEEE 754) :

Points essentiels

  • La troncature est biaisée (vers zéro), l'arrondissement minimise l'erreur moyenne
  • Chaque opération flottante () introduit une erreur relative bornée par
  • L'absorption fait disparaître les petites quantités ajoutées aux grandes
  • L'ordre des opérations affecte le résultat final (perte d'associativité)
  • Les erreurs s'accumulent au fil des calculs

La prochaine leçon introduira les outils pour mesurer ces erreurs : les chiffres significatifs exacts.

Exercices de réflexion

Exercice 1 : Ordre des opérations

Considérez les trois nombres : , , .

  1. Calculez à la main en arithmétique exacte.
  2. Calculez à la main en arithmétique exacte.
  3. Expliquez pourquoi Python donne des résultats différents pour ces deux expressions.
  4. Généralisez : quelle règle devrait-on suivre pour minimiser les erreurs lors de sommations ?

Exercice 2 : Troncature vs arrondissement

Dans un système flottant fictif avec et chiffres de mantisse, calculez les représentations par troncature et par arrondissement des nombres suivants :

Pour chaque cas :

  • Normalisez le nombre sous la forme
  • Calculez et
  • Vérifiez que les erreurs relatives respectent les bornes et
💡

Indice

Rappel des bornes pour : .

Exercice 3 : Absorption en pratique

Écrivez un programme Python qui :

  1. Calcule la somme (un million de termes )
  2. Compare le résultat avec la valeur théorique
  3. Propose une méthode pour obtenir un résultat plus précis

Exercice 4 : Multiplication et précision

Dans un système , calculez pas à pas le produit .

  1. Représentez chaque opérande en notation flottante normalisée.
  2. Effectuez la multiplication des mantisses.
  3. Additionnez les exposants.
  4. Renormalisez si nécessaire.
  5. Arrondissez à 3 chiffres.
  6. Comparez avec le résultat exact.