542 Stimmen

JavaScript Math, auf zwei Dezimalstellen runden

Ich habe die folgende JavaScript-Syntax:

var discount = Math.round(100 - (price / listprice) * 100);

Dies rundet auf die ganze Zahl auf. Wie kann ich das Ergebnis mit zwei Dezimalstellen zurückgeben?

973voto

Rick Calder Punkte 18120

HINWEIS - Siehe Änderung 4, wenn eine Präzision von 3 Dezimalstellen wichtig ist

var rabatt = (preis / listenpreis).toFixed(2);

toFixed rundet je nach Werten über 2 Dezimalstellen auf oder ab.

Beispiel: http://jsfiddle.net/calder12/tv9HY/

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

Bearbeiten - Wie von anderen erwähnt, wandelt dies das Ergebnis in einen String um. Um dies zu vermeiden:

var rabatt = +((preis / listenpreis).toFixed(2));

Bearbeiten 2 - Wie auch in den Kommentaren erwähnt, scheitert diese Funktion bei einiger Genauigkeit. Im Fall von 1.005 wird zum Beispiel 1.00 anstelle von 1.01 zurückgegeben. Wenn Genauigkeit in diesem Maße wichtig ist, habe ich diese Antwort gefunden: https://stackoverflow.com/a/32605063/1726511, die anscheinend gut funktioniert hat bei all den Tests, die ich ausprobiert habe.

Es ist jedoch eine geringfügige Änderung erforderlich: Die Funktion in der verlinkten Antwort gibt ganze Zahlen zurück, wenn sie auf eine gerundet wird. Zum Beispiel gibt 99.004 99 anstelle von 99.00 zurück, was nicht ideal ist für die Anzeige von Preisen.

Bearbeiten 3 - Es scheint, dass die Verwendung von toFixed beim eigentlichen Rückgabewert IMMER noch einige Zahlen durcheinander bringt. Dieses endgültige Bearbeiten scheint zu funktionieren. Mann, so viele Überarbeitungen!

var rabatt = roundTo((preis / listenpreis), 2);

function roundTo(n, dezimalstellen) {
  if (dezimalstellen === undefined) {
    dezimalstellen = 0;
  }

  var multiplikator = Math.pow(10, dezimalstellen);
  n = parseFloat((n * multiplikator).toFixed(11));
  var test = (Math.round(n) / multiplikator);
  return +(test.toFixed(dezimalstellen));
}

Siehe Fiddle-Beispiel hier: https://jsfiddle.net/calder12/3Lbhfy5s/

Bearbeiten 4 - Ihr bringt mich um. Bearbeitung 3 funktioniert nicht bei negativen Zahlen. Ohne näher darauf einzugehen, warum es einfacher ist, eine negative Zahl in eine positive umzuwandeln, bevor man rundet, und dann wieder zurückzuwandeln, bevor man das Ergebnis zurückgibt.

function roundTo(n, dezimalstellen) {
    var negativ = false;
    if (dezimalstellen === undefined) {
        dezimalstellen = 0;
    }
    if (n < 0) {
        negativ = true;
        n = n * -1;
    }
    var multiplikator = Math.pow(10, dezimalstellen);
    n = parseFloat((n * multiplikator).toFixed(11));
    n = (Math.round(n) / multiplikator).toFixed(dezimalstellen);
    if (negativ) {
        n = (n * -1).toFixed(dezimalstellen);
    }
    return n;
}

Fiddle: https://jsfiddle.net/3Lbhfy5s/79/

166voto

John Gietzen Punkte 47223

Wenn Sie ein unäres Pluszeichen verwenden, um eine Zeichenkette in eine Zahl zu konvertieren wie auf MDN dokumentiert.

Zum Beispiel:+discount.toFixed(2)

63voto

Arne H. Bitubekk Punkte 2805

Die Funktionen Math.round() und .toFixed() sind dazu gedacht, auf die nächste ganze Zahl zu runden. Sie erhalten inkorrekte Ergebnisse, wenn Sie mit Dezimalzahlen arbeiten und die "multiplizieren und dividieren" Methode für Math.round() oder den Parameter für .toFixed() verwenden. Wenn Sie beispielsweise versuchen, 1.005 mit Math.round(1.005 * 100) / 100 zu runden, erhalten Sie das Ergebnis von 1 und 1.00 mit .toFixed(2) anstelle der korrekten Antwort von 1.01.

Sie können folgendes verwenden, um dieses Problem zu lösen:

Number(Math.round(100 - (preis / listenpreis) * 100 + 'e2') + 'e-2');

Fügen Sie .toFixed(2) hinzu, um die gewünschten zwei Dezimalstellen zu erhalten.

Number(Math.round(100 - (preis / listenpreis) * 100 + 'e2') + 'e-2').toFixed(2);

Sie könnten eine Funktion erstellen, die das Runden für Sie übernimmt:

function round(wert, dezimalstellen) {
    return Number(Math.round(wert + 'e' + dezimalstellen) + 'e-' + dezimalstellen);
}

Beispiel: https://jsfiddle.net/k5tpq3pd/36/

Alternative

Sie können eine Rundungsfunktion zu Number hinzufügen, indem Sie Prototyp verwenden. Ich würde nicht empfehlen, hier .toFixed() hinzuzufügen, da es eine Zeichenfolge anstelle einer Zahl zurückgeben würde.

Number.prototype.round = function(dezimalstellen) {
    return Number((Math.round(this + "e" + dezimalstellen)  + "e-" + dezimalstellen));
}

und verwenden Sie es wie folgt:

var zuRundendeNummer = 100 - (preis / listenpreis) * 100;
zuRundendeNummer.round(2);
zuRundendeNummer.round(2).toFixed(2); //Konvertiert es in eine Zeichenfolge mit zwei Dezimalstellen

Beispiel https://jsfiddle.net/k5tpq3pd/35/

Quelle: http://www.jacklmoore.com/notes/rounding-in-javascript/

38voto

Cattode Punkte 846

Um das Ergebnis mit zwei Dezimalstellen zu erhalten, kannst du folgendes tun:

var rabatt = Math.round((100 - (preis / listenpreis) * 100) * 100) / 100;

Der zu rundende Wert wird mit 100 multipliziert, um die ersten beiden Ziffern zu behalten, dann teilen wir durch 100, um das tatsächliche Ergebnis zu erhalten.

33voto

Die beste und einfachste Lösung, die ich gefunden habe, ist

function round(value, decimals) {
 return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}   
round(1.005, 2); // 1.01

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X