JavaScript: arrondir à un certain nombre de décimales, mais supprimer les zéros supplémentaires

85

Voici le scénario: je reçois .9999999999999999quand je devrais être 1.0.
Je peux me permettre de perdre une décimale de précision, donc j'utilise .toFixed(15), quel genre de travail.

L'arrondi fonctionne, mais le problème est que je suis donné 1.000000000000000.
Existe-t-il un moyen d'arrondir à un certain nombre de décimales, mais de supprimer les espaces supplémentaires?

Remarque: ce .toPrecisionn'est pas ce que je veux; Je veux seulement spécifier le nombre de nombres après la virgule décimale.
Note 2: Je ne peux pas simplement utiliser .toPrecision(1)parce que je dois conserver la haute précision pour les nombres qui ont réellement des données après le point décimal. Idéalement, il y aurait exactement autant de décimales que nécessaire (jusqu'à 15).

Nathan
la source
Le fait est que .toFixed retourne une chaîne, donc simplement le faire passer par un nombre, puis revenir à une chaîne, le reconvertira sans les zéros de fin.
Neil
@Nathan: juste pour clarifier. Voulez-vous simplement supprimer les zéros de fin dans la chaîne que vous avez obtenue avec toFixed ()?
Jiri Kriz

Réponses:

141
>>> parseFloat(0.9999999.toFixed(4));
1
>>> parseFloat(0.0009999999.toFixed(4));
0.001
>>> parseFloat(0.0000009999999.toFixed(4));
0
Gus
la source
4
N'oubliez pas de les mettre entre parenthèses lorsque vous traitez des nombres négatifs: -2.34.toFixed(1)retourne en -2.3raison de la priorité des opérateurs .
Константин Ван
1
L'utilisation de l'opérateur unaire + devrait être plus rapide que la parseFloatfonction: +number.toFixed(13)Cette expression peut également être utilisée pour supprimer les inexactitudes de nombres JavaScript comme dans 1.0000000000000045.
ygoe le
37

Oui, il y a un moyen. Utilisez parseFloat().

parseFloat((1.005).toFixed(15)) //==> 1.005
parseFloat((1.000000000).toFixed(15)) //==> 1

Voir un exemple en direct ici: http://jsfiddle.net/nayish/7JBJw/

Nachshon Schwartz
la source
1
Ne fonctionne pas pour parseFloat("0.0000007"), ce qui donne"7e-7"
Matt Huggins
19

Si je comprends bien, vous souhaitez supprimer les zéros de fin dans la chaîne que vous avez obtenue via toFixed(). Ceci est une opération de chaîne pure:

var x = 1.1230000;
var y = x.toFixed(15).replace(/0+$/, "");  // ==> 1.123
Jiri Kriz
la source
6
Vous êtes le seul à avoir vraiment répondu à la question .. merci!
Mugen
4
Cela laisse le point sur les nombres ronds ("100.00" => "100")
pckill
5
@pckill si vous ne voulez pas que le point soit remplacé ( ...replace(/\.?0+$/, "");), vous pouvez l'inclure dans l'expression régulière .
Zach Snow
Cela échoue sur 0 et -0 car 0devient la chaîne vide "", et -0devient -, aucun d'entre eux n'est attendu (à une estimation). @ zach-snow votre solution suggérée échoue également sur 0 et -0.
robocat
@Mugen, quel était le problème avec la réponse de Gus?
trysis
9

Number(n.toFixed(15)) or +(n.toFixed(15)) convertira la chaîne décimale à 15 places en nombre, supprimant les zéros de fin.

Kennebec
la source
1
Je pensais que je le soulignerais, + (n.toFixed (...)) est beaucoup plus efficace que parseFloat. Je ne sais pas pourquoi, mais c'est aussi plus efficace que Number dans Chrome.
Domino
8

Si vous convertissez la valeur de retour en un nombre, ces zéros de fin seront supprimés. C'est aussi moins verbeux que cela ne l' parseFloat()est.

+(4.55555).toFixed(2);
//-> 4.56

+(4).toFixed(2);
//-> 4

Celui - ci utilise l' opérateur unaire + , donc si vous utilisez ce dans le cadre d'une opération de chaîne que vous devez avoir un infix + avant d' : var n=0.9999999999999999; console.log('output ' + +n.toFixed(2));. Pour info, un + unaire devant une chaîne le convertit en un nombre. Depuis MDN: Unary + peut:

convertir les représentations sous forme de chaîne d'entiers et de flottants, ainsi que les valeurs non-chaîne true, false et null. Les entiers aux formats décimal et hexadécimal (préfixe "0x") sont pris en charge. Les nombres négatifs sont pris en charge (mais pas pour l'hexagone). S'il ne peut pas analyser une valeur particulière, il évaluera à NaN.

CJ
la source
@robocat Je viens de faire une simple vérification; +(4.1).toFixed(4)est 4.1en Chrome 60 .
Константин Ван
Je ne comprends pas. Quelle est la raison pour laquelle cette réponse a été rejetée?
Константин Ван
@K Vous aviez raison, j'ai donc supprimé mon commentaire précédent et ajouté à la réponse (je pense que j'utilisais infix + avec une chaîne sur lhs, plutôt que d'utiliser correctement unary +. Habituellement, je suis plus prudent! Cheers)
robocat
Cette réponse fonctionne toujours avec NaN, Infinity, -Infinity, 3e30 et 0. Certaines autres réponses échouent dans certains cas de coin.
robocat
(4) .toFixed (2) -> "4.00" dans Chrome 60.0.3112.113
Daniel Que
1

Aucun de ceux-ci ne m'a vraiment donné ce que je recherchais en fonction du titre de la question, qui était, par exemple, 5,00 à 5 et 5.10 à 5,1. Ma solution était la suivante:

num.toFixed(places).replace(/\.?0+$/, '')

'5.00'.replace(/\.?0+$/, '') // 5
'5.10'.replace(/\.?0+$/, '') // 5.1
'5.0000001'.replace(/\.?0+$/, '') // 5.0000001
'5.0001000'.replace(/\.?0+$/, '') // 5.0001

Remarque: le regex ne fonctionne que si places > 0

PS https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed

Jenna Zeigen
la source
Échec 5e30(change le numéro en 5e3). Les cas de coin sont diaboliques!
robocat
0

Il existe une meilleure méthode qui conserve la précision et supprime également les zéros. Cela prend un nombre d'entrée et, grâce à la magie de la conversion, retirera tous les zéros de fin. J'ai trouvé que 16 était la limite de précision pour moi, ce qui est assez bon si vous ne mettez pas un satellite sur Pluton.

function convertToFixed(inputnum)
{

      var mynum = inputnum.toPrecision(16);
//If you have a string already ignore this first line and change mynum.toString to the inputnum

      var mynumstr = mynum.toString();
    return parseFloat(mynumstr);
    }
    alert(convertToFixed(6.6/6));
Kevrone
la source
0

La toFixed()méthode formate a à l' numberaide de la notation à virgule fixe et renvoie a string.

Il applique une stratégie d' arrondi à la moitié .

(0.124).toFixed(2); // returns 0.12
(0.125).toFixed(2); // returns 0.13

Comme vous l'avez décrit, cela entraînera également parfois des zéros de fin (potentiellement inutiles).

(0.001).toFixed(2); // returns 0.00

Vous ne voudrez peut-être pas vous débarrasser de ces zéros de fin, vous pouvez simplement le reconvertir en un number . Il existe de nombreuses façons de procéder.

+(0.001).toFixed(2); // the shortest

Pour un aperçu des différentes méthodes de conversion de chaînes en nombres, veuillez vérifier cette question, qui a d'excellentes réponses.

bvdb
la source