On additionne mille fois
Exercice d'entraînement · niveau 3 (difficile) · NSI (première), chapitre 2 — Flottants, booléens et textes · Automatiser le développement binaire
Énoncé
On additionne mille fois. (a) Le résultat vaut-il ? (b) Mesurer l'écart. (c) Comparer avec math.fsum et avec la somme des mêmes valeurs triées par ordre croissant. Que conclure sur la propagation des erreurs ?
Corrigé
import math
def somme_naive(t):
"""Somme de gauche a droite, avec un arrondi par addition."""
s = 0.0
for x in t:
s = s + x
return s
>>> t = [0.1] * 1000
>>> somme_naive(t)
99.9999999999986
>>> somme_naive(t) == 100.0
False
>>> abs(somme_naive(t) - 100.0)
1.4068746168049984e-12
>>> math.fsum(t)
100.0
(a) Non, et il ne pouvait pas en être autrement : n'est pas exact, chacune des mille additions arrondit, et les erreurs s'accumulent.
(b) L'écart vaut . Il est minuscule dans l'absolu — mais il est dix mille fois plus grand que l'erreur d'une seule addition (). C'est le point à retenir : l'erreur croît avec le nombre d'opérations.
(c) Ici tous les termes sont égaux, donc le tri ne change rien. En revanche math.fsum rend exactement : il garde une trace des bits perdus et corrige à la fin. Le tri croissant, lui, aide dès que les termes ont des ordres de grandeur différents — on additionne les petits entre eux avant qu'un gros ne les absorbe.
Contrôle : math.isclose(somme_naive(t), 100.0) rend True : la tolérance relative absorbe sans peine une erreur de relatif. Le résultat est bon ; c'est le test d'égalité qui était mauvais.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.