Standard IEEE 754 pour les nombres à virgule flottante : comprendre l'arithmétique informatique
Si vous avez déjà programmé, vous avez probablement rencontré un phénomène étrange : 0.1 + 0.2 n'est pas égal à 0.3. À la place, vous obtenez quelque chose comme 0.30000000000000004. Ce n'est pas un bug de votre langage de programmation ; c'est une conséquence fondamentale de la manière dont les ordinateurs représentent les nombres réels en utilisant le standard IEEE 754.
Dans ce guide, nous allons démystifier la norme IEEE 754, expliquer comment les nombres à virgule flottante sont stockés et donner des conseils pour gérer les problèmes de précision dans votre code.
Qu'est-ce que l'IEEE 754 ?
La norme IEEE sur l'arithmétique à virgule flottante (IEEE 754) est la norme la plus largement utilisée pour le calcul à virgule flottante. Établie en 1985, elle définit les formats de représentation des nombres réels en binaire et les opérations effectuées sur ceux-ci.
Les formats les plus courants sont :
- Simple précision (32 bits) : Utilisé pour les
floaten C/C++/Java. - Double précision (64 bits) : Utilisé pour les
doubleen C/C++/Java et constitue le type de nombre par défaut en JavaScript et Python.
Comment ça marche : l'anatomie d'un flottant
Un nombre à virgule flottante est représenté d'une manière similaire à la notation scientifique ($1.23 \times 10^4$), mais en binaire. Il se compose de trois parties :
- Bit de signe (1 bit) :
0pour positif,1pour négatif. - Exposant : Détermine l'échelle du nombre.
- Mantisse (Significande) : Représente les chiffres significatifs.
Structure de la double précision 64 bits :
- Signe : 1 bit
- Exposant : 11 bits
- Mantisse : 52 bits
La formule utilisée est : $(-1)^{signe} \times (1.mantisse) \times 2^{exposant - biais}$
Pourquoi $0.1 + 0.2 \neq 0.3$ ?
La cause fondamentale est que la plupart des fractions décimales ne peuvent pas être représentées exactement en binaire.
- En base 10, une fraction peut être représentée exactement si les facteurs premiers de son dénominateur sont uniquement 2 et 5 (les facteurs de 10).
- En base 2, une fraction ne peut être représentée exactement que si les facteurs premiers de son dénominateur sont uniquement 2.
$0.1$ est $1/10$. Comme 10 possède un facteur 5, il devient une séquence répétitive infinie en binaire :
0.00011001100110011...
Les ordinateurs doivent arrondir cette séquence infinie pour qu'elle tienne dans 32 ou 64 bits, ce qui entraîne les minuscules erreurs que nous observons.
Valeurs spéciales
L'IEEE 754 définit également plusieurs valeurs spéciales pour gérer les cas limites :
- NaN (Not a Number) : Résultat d'opérations indéfinies (ex:
0/0). - Infini ($\infty$) : Résultat d'un dépassement de capacité ou d'une division par zéro (
1/0). - Zéro négatif (-0) : Distinct du zéro positif dans certains calculs.
Bonnes pratiques pour les développeurs
- N'utilisez jamais
==pour les flottants : Vérifiez toujours si la différence est inférieure à une valeur minuscule (epsilon).if (Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON) { ... } - Utilisez des décimaux pour l'argent : Pour les calculs financiers, utilisez des bibliothèques spécialisées (comme
decimal.js) ou stockez les valeurs sous forme d'entiers (ex: centimes au lieu de dollars). - Attention à la plage : La double précision peut représenter de très grands nombres, mais la précision diminue à mesure que les nombres augmentent.
FAQ
Q : La virgule flottante est-elle non déterministe ? R : Généralement, non. Avec les mêmes entrées et le même mode d'arrondi, l'IEEE 754 devrait produire les mêmes résultats. Cependant, différents compilateurs ou instructions CPU (comme FMA) peuvent entraîner de légères variations.
Q : Qu'est-ce que "BigInt" ? R : BigInt (en JS) gère les entiers de précision arbitraire. Il ne gère pas les fractions. Pour les fractions, vous avez besoin d'une bibliothèque Decimal.
Q : Combien de chiffres décimaux de précision un double possède-t-il ? R : Un double 64 bits possède environ 15 à 17 chiffres décimaux significatifs.
Outils connexes
- Convertisseur d'unités - Effectuez des conversions précises entre différentes unités de mesure.
- Formateur JSON - Inspectez la représentation des nombres dans les données JSON.
- Générateur de hachage - Vérifiez l'intégrité des données lorsque chaque bit compte.