JavaScript: Auf eine Anzahl von Dezimalstellen runden, aber zusätzliche Nullen entfernen

85

Hier ist das Szenario: Ich bekomme, .9999999999999999wann ich bekommen sollte 1.0.
Ich kann es mir leisten, eine Dezimalstelle der Genauigkeit zu verlieren, also benutze ich .toFixed(15), welche Art von Arbeit.

Die Rundung funktioniert, aber das Problem ist, dass ich gegeben bin 1.000000000000000.
Gibt es eine Möglichkeit, auf mehrere Dezimalstellen zu runden, aber zusätzliche Leerzeichen zu entfernen?

Hinweis: .toPrecisionist nicht das, was ich will; Ich möchte nur angeben, wie viele Zahlen nach dem Dezimalpunkt stehen.
Hinweis 2: Ich kann nicht einfach verwenden, .toPrecision(1)da ich die hohe Genauigkeit für Zahlen beibehalten muss, deren Daten tatsächlich nach dem Dezimalpunkt liegen. Im Idealfall gibt es genau so viele Dezimalstellen wie nötig (bis zu 15).

Nathan
quelle
Der Punkt ist, dass .toFixed einen String zurückgibt. Wenn Sie ihn also nur über eine Zahl und dann zurück zu einem String runden, wird er ohne die nachgestellten Nullen wieder konvertiert.
Neil
@ Nathan: nur zur Klarstellung. Möchten Sie nur die nachgestellten Nullen in der Zeichenfolge entfernen, die Sie mit toFixed () erhalten haben?
Jiri Kriz

Antworten:

140
>>> parseFloat(0.9999999.toFixed(4));
1
>>> parseFloat(0.0009999999.toFixed(4));
0.001
>>> parseFloat(0.0000009999999.toFixed(4));
0
Gus
quelle
4
Vergessen Sie nicht, sie in Klammern zu setzen, wenn Sie negative Zahlen behandeln: -2.34.toFixed(1)Rückgabe -2.3aufgrund der Priorität des Operators .
Константин Ван
1
Die Verwendung des Operators unary + sollte schneller sein als die parseFloatFunktion: +number.toFixed(13)Dieser Ausdruck kann auch verwendet werden, um Ungenauigkeiten der JavaScript-Nummer wie in 1.0000000000000045 zu entfernen.
Ygoe
35

Ja, es gibt einen Weg. Verwenden Sie parseFloat().

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

Ein Live-Beispiel finden Sie hier: http://jsfiddle.net/nayish/7JBJw/

Nachshon Schwartz
quelle
1
Funktioniert nicht für parseFloat("0.0000007"), was gibt"7e-7"
Matt Huggins
18

Soweit ich weiß, möchten Sie die nachgestellten Nullen in der Zeichenfolge entfernen, die Sie über erhalten haben toFixed(). Dies ist eine reine Zeichenfolgenoperation:

var x = 1.1230000;
var y = x.toFixed(15).replace(/0+$/, "");  // ==> 1.123
Jiri Kriz
quelle
6
Du bist der einzige, der die Frage wirklich beantwortet hat. Danke!
Mugen
4
Dies lässt den Punkt auf runden Zahlen ("100.00" => "100.")
pckill
5
@pckill Wenn Sie nicht möchten, dass der Punkt in den regulären Ausdruck aufgenommen wird, der ersetzt werden soll ( ...replace(/\.?0+$/, "");).
Zach Snow
Das schlägt bei 0 und -0 fehl, weil es 0die leere Zeichenfolge ""wird und -0wird -, von denen keine erwartet wird (bei einer Vermutung). @ zach-snow Ihre vorgeschlagene Lösung schlägt auch bei 0 und -0 fehl.
Robocat
@Mugen, was war das Problem mit Gus 'Antwort?
Tryse
9

Number(n.toFixed(15)) or +(n.toFixed(15)) konvertiert die 15-stellige Dezimalzeichenfolge in eine Zahl und entfernt nachfolgende Nullen.

kennebec
quelle
1
Ich dachte, ich würde darauf hinweisen, + (n.toFixed (...)) ist viel effizienter als parseFloat. Ich weiß nicht warum, aber es ist auch effizienter als Number in Chrome.
Domino
8

Wenn Sie den Rückgabewert in eine Zahl umwandeln, werden diese nachgestellten Nullen gelöscht. Dies ist auch weniger ausführlich als es parseFloat()ist.

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

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

Dies verwendet den unären Operator +. Wenn Sie diesen als Teil einer Zeichenfolgenoperation verwenden, müssen Sie ein Infix + davor haben : var n=0.9999999999999999; console.log('output ' + +n.toFixed(2));. Zu Ihrer Information, ein unäres + vor einem String konvertiert es in eine Zahl. Von MDN: Unary + kann:

Konvertieren Sie Zeichenfolgendarstellungen von Ganzzahlen und Gleitkommazahlen sowie die Nicht-Zeichenfolgenwerte true, false und null. Ganzzahlen in den Formaten Dezimal und Hexadezimal ("0x") werden unterstützt. Negative Zahlen werden unterstützt (jedoch nicht für Hex). Wenn ein bestimmter Wert nicht analysiert werden kann, wird NaN ausgewertet.

CJ
quelle
@robocat Ich habe gerade eine einfache Überprüfung durchgeführt; +(4.1).toFixed(4)ist 4.1in Chrome 60 .
Константин Ван
Ich verstehe es nicht Was war der Grund, warum diese Antwort abgelehnt wurde?
28онстантин Ван
@K Du hattest Recht, also habe ich meinen vorherigen Kommentar gelöscht und der Antwort hinzugefügt (ich glaube, ich habe infix + mit einem String auf lhs verwendet, anstatt unary + korrekt zu verwenden. Normalerweise bin ich vorsichtiger! Prost)
robocat
Diese Antwort funktioniert immer noch mit NaN, Infinity, -Infinity, 3e30 und 0. Einige andere Antworten schlagen in einigen Eckfällen fehl.
Robocat
(4) .toFixed (2) -> "4.00" in Chrome 60.0.3112.113
Daniel Que
1

Keines davon hat mir wirklich das gebracht, wonach ich gesucht habe, basierend auf dem Fragentitel, der zum Beispiel für 5,00 zu 5 und 5,10 zu 5,1 war. Meine Lösung war wie folgt:

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

Hinweis: Die Regex funktioniert nur, wenn places > 0

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

Jenna Zeigen
quelle
Schlägt ein 5e30(ändert die Nummer in 5e3). Eckfälle sind teuflisch!
Robocat
0

Es gibt eine bessere Methode, die die Präzision beibehält und auch die Nullen entfernt. Dies erfordert eine eingegebene Nummer und zieht durch etwas Magie des Castings alle nachgestellten Nullen ab. Ich habe festgestellt, dass 16 die Genauigkeitsgrenze für mich ist, was ziemlich gut ist, wenn Sie keinen Satelliten auf Pluto setzen.

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
quelle
0

Die toFixed()Methode formatiert a unter numberVerwendung der Festkommanotation und gibt a zurück string.

Es wird eine Rundungsstrategie angewendet.

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

Wie Sie beschrieben haben, führt dies in der Tat manchmal auch zu (möglicherweise unnötigen) nachgestellten Nullen.

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

Möglicherweise möchten Sie diese nachgestellten Nullen nicht entfernen. Im Wesentlichen können Sie sie einfach wieder in a konvertieren number. Es gibt viele Möglichkeiten, dies zu tun.

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

Um einen Überblick über die verschiedenen Methoden zum Konvertieren von Zeichenfolgen in Zahlen zu erhalten, überprüfen Sie bitte diese Frage, die einige hervorragende Antworten enthält.

bvdb
quelle