Comment formater des nombres avec 2 décimales en JavaScript

Afficher des nombres avec exactement 2 décimales pour les prix, pourcentages et mesures

Introduction

De nombreuses applications doivent afficher des nombres avec un nombre fixe de décimales. Les prix affichent généralement deux décimales comme 19,99 €. Les pourcentages s'affichent souvent comme 45,50 %. Les mesures utilisent un nombre cohérent de décimales pour la lisibilité comme 3,14 mètres.

Contrôler les décimales garantit une cohérence visuelle dans votre application. Sans formatage explicite, JavaScript affiche les nombres avec un nombre variable de décimales en fonction de leur valeur réelle. Le nombre 5 s'affiche comme "5" tandis que 5,5 s'affiche comme "5.5", créant un alignement et une apparence incohérents.

Cette leçon montre comment formater des nombres avec exactement 2 décimales, ou jusqu'à 2 décimales, d'une manière qui respecte les différentes conventions locales.

Utiliser toFixed() pour un formatage de base

La méthode toFixed() convertit un nombre en chaîne de caractères avec un nombre spécifié de décimales. Passez le nombre de décimales comme argument.

const price = 19.9;
const formatted = price.toFixed(2);
console.log(formatted);
// Output: "19.90"

La méthode affiche toujours exactement 2 décimales. Si le nombre a moins de décimales, toFixed() complète avec des zéros. S'il a plus de décimales, la méthode arrondit à 2 décimales.

const examples = [5, 5.5, 5.555, 5.999];

examples.forEach(num => {
  console.log(num.toFixed(2));
});
// Output:
// "5.00"
// "5.50"
// "5.56"
// "6.00"

La méthode toFixed() renvoie une chaîne de caractères, pas un nombre. C'est intentionnel car les zéros de fin ont une signification pour l'affichage mais seraient perdus s'ils étaient renvoyés comme un nombre.

Le problème de locale avec toFixed()

La méthode toFixed() utilise toujours un point comme séparateur décimal, quelle que soit la locale de l'utilisateur. De nombreux pays utilisent une virgule comme séparateur décimal au lieu d'un point.

const price = 19.99;
console.log(price.toFixed(2));
// Output: "19.99" (always uses period)

Pour les utilisateurs en Allemagne, France, Espagne et de nombreux autres pays, cela semble incorrect. Ils s'attendent à voir "19,99" au lieu de "19.99". La méthode toFixed() ne peut pas produire un résultat adapté aux conventions locales.

Pour formater correctement les nombres selon différentes conventions locales, utilisez l'API Intl.NumberFormat.

Utiliser Intl.NumberFormat pour un formatage adapté aux conventions locales

L'API Intl.NumberFormat formate les nombres selon les conventions locales. Créez un formateur avec une locale et des options, puis appelez sa méthode format() avec un nombre.

const formatter = new Intl.NumberFormat("de-DE", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

const price = 19.99;
console.log(formatter.format(price));
// Output: "19,99" (uses comma for German locale)

Le même formateur produit des résultats différents pour différentes locales.

const price = 19.99;

const usFormatter = new Intl.NumberFormat("en-US", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

const deFormatter = new Intl.NumberFormat("de-DE", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

console.log(usFormatter.format(price));
// Output: "19.99"

console.log(deFormatter.format(price));
// Output: "19,99"

Le séparateur décimal change automatiquement en fonction de la locale.

Formater avec exactement 2 décimales

Pour afficher exactement 2 décimales, définissez minimumFractionDigits et maximumFractionDigits à 2. Cela garantit que le résultat a toujours 2 décimales, en complétant avec des zéros si nécessaire et en arrondissant lorsque le nombre a plus de précision.

const formatter = new Intl.NumberFormat("en-US", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

console.log(formatter.format(5));
// Output: "5.00"

console.log(formatter.format(5.5));
// Output: "5.50"

console.log(formatter.format(5.555));
// Output: "5.56"

L'option minimumFractionDigits contrôle les zéros de fin. Sans elle, les nombres avec moins de décimales n'afficheraient pas les zéros.

const withoutMinimum = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 2
});

console.log(withoutMinimum.format(5));
// Output: "5"

const withMinimum = new Intl.NumberFormat("en-US", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

console.log(withMinimum.format(5));
// Output: "5.00"

Définir les deux options à la même valeur garantit un nombre de décimales cohérent pour tous les nombres.

Formater avec jusqu'à 2 décimales

Parfois, vous souhaitez afficher les décimales uniquement lorsque nécessaire, jusqu'à un maximum de 2. Définissez maximumFractionDigits à 2 et minimumFractionDigits à 0 ou omettez-le entièrement.

const formatter = new Intl.NumberFormat("en-US", {
  minimumFractionDigits: 0,
  maximumFractionDigits: 2
});

console.log(formatter.format(5));
// Output: "5"

console.log(formatter.format(5.5));
// Output: "5.5"

console.log(formatter.format(5.555));
// Output: "5.56"

Cette approche supprime les zéros de fin tout en limitant la précision à 2 décimales. Elle fonctionne bien pour afficher des mesures ou des statistiques où les zéros de fin n'apportent aucune information.

La valeur par défaut pour minimumFractionDigits est 0 pour le formatage de nombres simples, vous pouvez donc l'omettre.

const formatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 2
});

console.log(formatter.format(5));
// Output: "5"

console.log(formatter.format(5.5));
// Output: "5.5"

Réutiliser les formateurs pour de meilleures performances

Créer une nouvelle instance de Intl.NumberFormat est relativement coûteux. Si vous formatez de nombreux nombres avec les mêmes options, créez le formateur une fois et réutilisez-le.

const formatter = new Intl.NumberFormat("en-US", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

const prices = [19.99, 29.5, 99, 149.999];

prices.forEach(price => {
  console.log(formatter.format(price));
});
// Output:
// "19.99"
// "29.50"
// "99.00"
// "150.00"

Ce modèle est plus efficace que de créer un nouveau formateur pour chaque nombre.

Quand utiliser chaque approche

Utilisez exactement 2 décimales lors de l'affichage de prix, de montants en devises ou de toute valeur où les décimales ont une signification sémantique. Afficher "5,00 €" au lieu de "5 €" indique la précision et correspond aux attentes des utilisateurs pour les prix.

Utilisez jusqu'à 2 décimales lors de l'affichage de statistiques, de mesures ou de valeurs calculées où les zéros de fin n'ajoutent aucune information. Afficher "5 mètres" au lieu de "5,00 mètres" est plus clair et plus lisible.

Utilisez toFixed() uniquement lorsque vous êtes certain que tous vos utilisateurs utilisent la même convention de séparateur décimal, ou lorsque la sortie n'est pas destinée aux utilisateurs. Pour les applications internationalisées, préférez Intl.NumberFormat.

Utiliser la locale préférée de l'utilisateur

Au lieu de coder en dur une locale, utilisez les préférences linguistiques du navigateur de l'utilisateur. La propriété navigator.language fournit la locale préférée de l'utilisateur.

const formatter = new Intl.NumberFormat(navigator.language, {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

const price = 19.99;
console.log(formatter.format(price));
// Output varies by user's locale
// For en-US: "19.99"
// For de-DE: "19,99"
// For fr-FR: "19,99"

Vous pouvez également passer l'intégralité du tableau navigator.languages pour permettre à l'API Intl de sélectionner la première locale prise en charge parmi les préférences de l'utilisateur.

const formatter = new Intl.NumberFormat(navigator.languages, {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

Cette approche fournit un repli automatique si la première préférence de l'utilisateur n'est pas prise en charge.