271 votes

Supprimez les zéros de fin non significatifs d'un nombre ?

Ai-je manqué un appel standard de l'API qui supprime les zéros insignifiants d'un nombre ?

var x = 1.234000; // to become 1.234
var y = 1.234001; // stays 1.234001

Number.toFixed() y Number.toPrecision() ne sont pas tout à fait ce que je recherche.

6 votes

Hum, 1.234000 === 1.234 .

5 votes

Oui, si vous faites alert(x), il s'affiche sans les zéros de fin.

79 votes

Après avoir travaillé avec un certain nombre de clients, je peux témoigner que même si 1,234000 === 1,234, les clients ne veulent pas voir ces zéros supplémentaires s'ils n'en ont pas besoin.

381voto

Gary Points 1655

J'ai eu un cas similaire où je voulais utiliser .toFixed() lorsque c'est nécessaire, mais je ne voulais pas de remplissage lorsque ce n'était pas le cas. J'ai donc fini par utiliser parseFloat en conjonction avec toFixed.

toFixed sans rembourrage

parseFloat(n.toFixed(4));

Une autre option qui fait presque la même chose
Cette réponse peut vous aider à prendre votre décision

Number(n.toFixed(4));

toFixed arrondit le nombre à une longueur spécifique, mais le convertit également en chaîne de caractères. La reconversion en un type numérique rendra non seulement le nombre plus sûr pour l'utilisation arithmétique, mais supprimera aussi automatiquement les 0 de fin de chaîne. Par exemple :

var n = "1.234000";
    n = parseFloat(n);
 // n is 1.234 and in number form

Parce que même si vous définissez un nombre avec des zéros à la fin, ils sont abandonnés.

var n = 1.23000;
 // n == 1.23;

2 votes

Notez que cela ne fonctionne que si le nombre pertinent de décimales est égal ou supérieur à l'argument toFixed. Si le nombre est par exemple 1.200000, le résultat de toFixed(3) sera 1.200 et donc, aucun des zéros de fin ne sera supprimé.

0 votes

@LeopoldoSanczyk Non, ce n'est vrai que si vous utilisez simplement toFixed, car il renvoie une chaîne. Les types de nombres perdent automatiquement les zéros de fin. C'est pourquoi j'ai utilisé les deux en tandem.

1 votes

@Gary, je retire mon commentaire, j'ai vu parseFloat(n).toFixed(4); au lieu de votre réponse réelle. Je suis désolé.

185voto

Cristian Sanchez Points 11266

Si vous la convertissez en chaîne, elle n'affichera pas les zéros de fin, qui ne sont pas stockés dans la variable en premier lieu puisqu'elle a été créée en tant que nombre et non en tant que chaîne.

var n = 1.245000
var noZeroes = n.toString() // "1.245"

6 votes

J'étais sur le point de poster un code pour enlever les zéros mais la solution de Daniel semble fonctionner. Elle fonctionne même pour des chaînes de caractères telles que "1.2345000". ("1.2345000" * 1).toString() ; // devient 1.2345

8 votes

Bien sûr, si votre variable est déjà une chaîne de caractères, vous devez d'abord la convertir en un nombre, puis la reconvertir.

0 votes

Cela a bien fonctionné. J'avais le même problème, j'ai converti le float en string et ensuite parseFloat pour le récupérer dans le bon format, mais sans les zéros de fin.

59voto

w00t Points 1253

J'ai d'abord utilisé une combinaison des réponses de matti-lyra et de gary :

r=(+n).toFixed(4).replace(/\.0+$/,'')

Résultats :

  • 1234870.98762341: "1234870.9876"
  • 1230009100 : "1230009100"
  • 0.0012234 : "0.0012"
  • 0.1200234 : "0.12"
  • 0.000001231 : "0"
  • 0.10001 : "0.1000"
  • "asdf" : "NaN" (donc pas d'erreur d'exécution)

Le cas un peu problématique est celui de 0,10001. J'ai fini par utiliser cette version longue :

    r = (+n).toFixed(4);
    if (r.match(/\./)) {
      r = r.replace(/\.?0+$/, '');
    }
  • 1234870.98762341: "1234870.9876"
  • 1230009100 : "1230009100"
  • 0.0012234 : "0.0012"
  • 0.1200234 : "0.12"
  • 0.000001231 : "0"
  • 0.10001 : "0.1"
  • "asdf" : "NaN" (donc pas d'erreur d'exécution)

Mise à jour : Et voici la nouvelle version de Gary (voir les commentaires) :

r=(+n).toFixed(4).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/,'$1')

Cela donne les mêmes résultats que ci-dessus.

1 votes

J'ai une solution purement regex qui, je crois, fonctionne. toFixed(4).replace(/([0-9]+(\.[1-9]+)?)(\.?0+$)/,"$1")

0 votes

@Gary plus proche, maintenant échoue pour 1.01010 :-)

1 votes

Gah ! Apparemment, je ne suis pas aussi bon que d'autres pour casser mes propres RegEx. Je ne laisserai pas cela me battre ! J'ai comparé celui-ci à tous vos cas de test et à tous les cas (valides) auxquels j'ai pu penser. ([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)

19voto

dperish Points 53

J'avais pratiquement la même exigence, et j'ai constaté qu'il n'existe pas de mécanisme intégré pour cette fonctionnalité.

Outre la suppression des zéros de fin, j'ai également dû arrondir et formater la sortie pour la locale actuelle de l'utilisateur (c'est-à-dire 123 456 789).

Tout mon travail sur ce sujet a été inclus dans prettyFloat.js (sous licence MIT) sur GitHub : https://github.com/dperish/prettyFloat.js


Exemples d'utilisation :

prettyFloat(1.111001, 3) // "1.111"
prettyFloat(1.111001, 4) // "1.111"
prettyFloat(1.1111001, 5) // "1.1111"
prettyFloat(1234.5678, 2) // "1234.57"
prettyFloat(1234.5678, 2, true) // "1,234.57" (en-us)


Mise à jour - août 2018


Tous les navigateurs modernes prennent désormais en charge la fonction API d'internationalisation ECMAScript qui permet de comparer des chaînes de caractères en fonction de la langue, de formater des nombres et de formater la date et l'heure.

const formatters = {
    default: new Intl.NumberFormat(),
    currency: new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0 }),
    whole: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 0, maximumFractionDigits: 0 }),
    oneDecimal: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 1, maximumFractionDigits: 1 }),
    twoDecimal: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 2, maximumFractionDigits: 2 })
};

formatters.twoDecimal.format(1234.5678);  // result: "1,234.57"
formatters.currency.format(28761232.291); // result: "$28,761,232"

Pour les navigateurs plus anciens, vous pouvez utiliser ce polyfill : https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en

0 votes

C'est ce que nous recherchons. Vous devez créer un paquet npm.

0 votes

Je devrais donc probablement mettre à jour ce document, car cela est désormais possible via l'API d'internationalisation.

2 votes

C'est très utile, merci de partager et merci aussi pour la mise à jour.

-1voto

Moon Points 1

Voici une solution possible :

var x = 1.234000 // to become 1.234;
var y = 1.234001; // stays 1.234001

eval(x) --> 1.234
eval(y) --> 1.234001

4 votes

Vous n'avez pas besoin de l'évaluation pour cette tâche simple ! parseFloat() sera très approprié.

9 votes

Eval == mal. Ne l'utilisez jamais

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X