La magie des nombres : pourquoi 0.1 + 0.2 n'est pas égal à 0.3 ?
Bonjour, futur gourou de JavaScript ! Si tu as déjà essayé d'additionner 0.1 et 0.2 dans la console du navigateur, tu as probablement eu un choc culturel :
console.log(0.1 + 0.2); // Affiche : 0.30000000000000004Oui, oui, JavaScript n'est pas devenu fou. C'est un problème standard de l'arithmétique à virgule flottante (IEEE 754). Les ordinateurs ne peuvent tout simplement pas représenter parfaitement 0.1 en binaire — c'est comme essayer d'écrire 1/3 en décimal. On obtient une fraction infinie.
Et là apparaît la question classique sur Stack Overflow, qui a recueilli des milliers de vues : « How to round to at most 2 decimal places, if necessary ». Comment afficher un nombre joliment, sans la traîne de « 0000000004 » ? Comment arrondir à deux décimales, mais seulement si nécessaire ?
Dans cet article, nous allons détailler un tutoriel pas à pas qui résoudra le problème une fois pour toutes. Tu découvriras pourquoi toFixed() ment parfois, comment fonctionne Math.round() et quelle méthode choisir pour une boutique en ligne, une calculatrice ou simplement pour un affichage élégant d'un prix.
Problème : « Je veux 2 décimales, mais pas plus ! »
Imagine que tu écris un panier d'achats. Le prix d'un article est de 10.00. Tu veux afficher 10, pas 10.00. Mais si le prix est 10.456, tu veux afficher 10.46. La logique est simple : on arrondit à deux décimales, mais on supprime les zéros inutiles.
La méthode standard toFixed(2) fait ceci :
const price = 10;console.log(price.toFixed(2)); // "10.00" — alors qu'on veut "10"
const price2 = 10.456;console.log(price2.toFixed(2)); // "10.46" — ici c'est bonProblème : toFixed() retourne toujours une chaîne de caractères et ajoute toujours des zéros. Cela ne convient pas.
Deuxième nuance — toFixed() peut arrondir étrangement à cause de la même virgule flottante :
console.log((1.005).toFixed(2)); // "1.00" — alors que ça devrait être "1.01" !Bingo ! Voilà pourquoi la question sur Stack Overflow est si populaire. Penchons-nous sur les solutions.
Solution n°1 : Arrondi mathématique (Math.round)
La méthode la plus fiable est de multiplier le nombre par 100, arrondir, puis diviser à nouveau. Cela fonctionne ainsi :
function roundToTwo(num) { return Math.round(num * 100) / 100;}
console.log(roundToTwo(10.456)); // 10.46console.log(roundToTwo(10)); // 10console.log(roundToTwo(1.005)); // 1 — oups, encore un problèmeTu vois ? 1.005 * 100 = 100.49999999999999 (à cause d'IEEE 754). Math.round arrondit cela vers le bas, on obtient 100, on divise par 100 = 1. Pas bien.
Conclusion : Cette méthode est bonne pour les cas simples, mais pas pour les calculs financiers. Pour des exemples pédagogiques, ça peut aller.
Solution n°2 : Number.EPSILON — le sauveur de précision
Pour vaincre l'erreur de virgule flottante, on peut ajouter un tout petit delta — Number.EPSILON. C'est la différence minimale entre deux nombres que JavaScript peut distinguer (environ 2.2e-16).
function roundToTwo(num) { return Math.round((num + Number.EPSILON) * 100) / 100;}
console.log(roundToTwo(1.005)); // 1.01 — ça marche !console.log(roundToTwo(10.456)); // 10.46console.log(roundToTwo(10)); // 10Pourquoi cela fonctionne-t-il ? Nous poussons le nombre très légèrement vers le haut, pour que 100.4999... devienne 100.5... et soit arrondi correctement.
Important : Cette méthode n'est pas parfaite pour tous les cas extrêmes, mais pour 99% des tâches, c'est une excellente solution. C'est précisément celle qui est souvent recommandée sur Stack Overflow.
Solution n°3 : toFixed() + Number() — une astuce maline
Une autre méthode populaire consiste à utiliser toFixed(2), puis à reconvertir la chaîne en nombre avec Number() ou le plus unaire +. Les zéros inutiles dis