Formatieren einer Zahl mit genau zwei Dezimalstellen in JavaScript

571

Ich habe diese Codezeile, die meine Zahlen auf zwei Dezimalstellen rundet. Aber ich bekomme Zahlen wie diese: 10.8, 2.4 usw. Dies sind nicht meine Vorstellung von zwei Dezimalstellen. Wie kann ich also Folgendes verbessern?

Math.round(price*Math.pow(10,2))/Math.pow(10,2);

Ich möchte Zahlen wie 10.80, 2.40 usw. Die Verwendung von jQuery ist für mich in Ordnung.

Abs
quelle
1
Ihr Code ist genau das, wonach ich gesucht habe (um die Float-Genauigkeit für kleinere JSON-Dateien auf 7 Dezimalstellen zu reduzieren). Math.pow für Geschwindigkeit überspringen val = Math.round (val * 10000000) / 10000000);
Pawel
Da die derzeit akzeptierte Antwort gibt wohl ein falsches Ergebnis für ein breites Spektrum von Werten durch Unschärfen inhärente in den Zahlen erschwerenden ( 0.565, 0.575, 1.005), kann ich bei der Suche wieder vorschlagen , diese Antwort , die bekommt sie richtig?
TJ Crowder
Vielleicht möchten Sie eine Sprintf-Bibliothek für JavaScript stackoverflow.com/questions/610406/…
Thilo
Nach dem korrekten Runden mit der Dezimalstellenverschiebungs- und Rundungsmethode können Sie die number.toFixed(x)Methode verwenden, um sie in eine Zeichenfolge mit der erforderlichen Anzahl von Nullen zu konvertieren. ZB rund 1.34um 1.3mit der Cross-Browser - Methode fügen Sie dann 1 Null und Konvertit String mit 1.3.toFixed(2)(zu erhalten "1.30").
Edward

Antworten:

999

Um eine Zahl in Festkommanotation zu formatieren, können Sie einfach die toFixed- Methode verwenden:

(10.8).toFixed(2); // "10.80"

var num = 2.4;
alert(num.toFixed(2)); // "2.40"

Beachten Sie, dass toFixed()eine Zeichenfolge zurückgegeben wird.

WICHTIG : Beachten Sie, dass toFixed nicht 90% der Zeit rundet, sondern den gerundeten Wert zurückgibt, aber in vielen Fällen nicht funktioniert.

Zum Beispiel:

2.005.toFixed(2) === "2.00"

AKTUALISIEREN:

Heutzutage können Sie den Intl.NumberFormatKonstruktor verwenden. Es ist Teil der ECMAScript Internationalization API Specification (ECMA402). Es hat eine ziemlich gute Browserunterstützung , einschließlich sogar IE11, und es wird in Node.js vollständig unterstützt .

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

console.log(formatter.format(2.005)); // "2.01"
console.log(formatter.format(1.345)); // "1.35"

Sie können alternativ die toLocaleStringMethode verwenden, die intern die IntlAPI verwendet:

const format = (num, decimals) => num.toLocaleString('en-US', {
   minimumFractionDigits: 2,      
   maximumFractionDigits: 2,
});


console.log(format(2.005)); // "2.01"
console.log(format(1.345)); // "1.35"

Diese API bietet Ihnen auch eine Vielzahl von Formatierungsoptionen, z. B. tausend Trennzeichen, Währungssymbole usw.

CMS
quelle
17
Funktioniert nicht konsistent in allen Browsern, dh (0.09).toFixed(1);gibt in IE8 0.0 an
ajbeaven
41
fest rundet nicht, Sie können es zuerst tun: (Math.round (0.09)). toFixed (1);
rekans
32
@rekans: Das ist falsch. Math.Round(0.09)wird zurückkehren, 0so wird dies immer geben 0.0...
Chris
28
Dies ist in den meisten Situationen eine schlechte Idee. In einigen Fällen wird die Zahl in eine Zeichenfolge oder eine Gleitkommazahl konvertiert.
Ash Blue
80
Muss hier mit @AshBlue übereinstimmen ... dies ist nur für die Formatierung der Darstellung von Werten sicher. Kann Code mit weiteren Berechnungen brechen. Ansonsten Math.round(value*100)/100funktioniert es besser für 2DP.
UpTheCreek
98

Dies ist ein altes Thema, aber immer noch die besten Google-Ergebnisse, und die angebotenen Lösungen haben dasselbe Problem mit Gleitkomma-Dezimalstellen. Hier ist die (sehr generische) Funktion, die ich dank MDN verwende :

function round(value, exp) {
  if (typeof exp === 'undefined' || +exp === 0)
    return Math.round(value);

  value = +value;
  exp = +exp;

  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));

  // Shift back
  value = value.toString().split('e');
  return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}

Wie wir sehen können, bekommen wir diese Probleme nicht:

round(1.275, 2);   // Returns 1.28
round(1.27499, 2); // Returns 1.27

Diese Großzügigkeit bietet auch einige coole Sachen:

round(1234.5678, -2);   // Returns 1200
round(1.2345678e+2, 2); // Returns 123.46
round("123.45");        // Returns 123

Um die Frage des OP zu beantworten, muss man Folgendes eingeben:

round(10.8034, 2).toFixed(2); // Returns "10.80"
round(10.8, 2).toFixed(2);    // Returns "10.80"

Oder für eine präzisere, weniger generische Funktion:

function round2Fixed(value) {
  value = +value;

  if (isNaN(value))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + 2) : 2)));

  // Shift back
  value = value.toString().split('e');
  return (+(value[0] + 'e' + (value[1] ? (+value[1] - 2) : -2))).toFixed(2);
}

Sie können es nennen mit:

round2Fixed(10.8034); // Returns "10.80"
round2Fixed(10.8);    // Returns "10.80"

Verschiedene Beispiele und Tests (danke an @ tj-crowder !):

astorije
quelle
1
Wie gibt es dafür keinen einfachen Weg? ES6 zur Rettung?
zero_cool
Vielen Dank, dass Sie die MDN-Polyfüllung veröffentlicht haben. Auf der verknüpften MDN-Seite ist die Polyfüllung nicht mehr vorhanden. Ich frage mich, warum es entfernt wurde ...
König Holly
43

Normalerweise füge ich dies meiner persönlichen Bibliothek hinzu, und nach einigen Vorschlägen und der Verwendung der @ Timineutron-Lösung, die dann für die Dezimallänge anpassbar ist, passt diese am besten:

function precise_round(num, decimals) {
   var t = Math.pow(10, decimals);   
   return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}

funktioniert für die gemeldeten Ausnahmen.

Miguel
quelle
2
präzise_runde (1,275,2) ist 1,27?
Allenhwkim
2
@Imre Ändere den Rückgabewert in (Math.round (num * Math.pow (10, Dezimalstellen)) / Math.pow (10, Dezimalstellen)). ToFixed (2); und Sie werden dieses Problem nicht mehr haben.
dkroy
6
Wo deklarieren Sie "sign" und "dec", wenn Ihre zweite Funktion so aufgenommen wird, wie sie ist, sollte sie nicht so undefiniert sein?
Ady Ngom
2
Ich habe einen Workarround für die Missign Sign-Methode im IE hinzugefügt
Armin
1
@Armin Mit Ihrem Fix funktioniert es auch in Safari. Die ursprüngliche Funktion funktionierte in Safari nicht.
Dave
19

Ich weiß nicht, warum ich einer vorherigen Antwort keinen Kommentar hinzufügen kann (vielleicht bin ich hoffnungslos blind, keine Ahnung), aber ich habe eine Lösung mit der Antwort von @ Miguel gefunden:

function precise_round(num,decimals) {
   return Math.round(num*Math.pow(10, decimals)) / Math.pow(10, decimals);
}

Und seine zwei Kommentare (von @bighostkim und @Imre):

  • Problem mit der precise_round(1.275,2)Nichtrückgabe von 1.28
  • Problem mit der precise_round(6,2)Nichtrückgabe von 6.00 (wie er wollte).

Meine endgültige Lösung lautet wie folgt:

function precise_round(num,decimals) {
    var sign = num >= 0 ? 1 : -1;
    return (Math.round((num*Math.pow(10,decimals)) + (sign*0.001)) / Math.pow(10,decimals)).toFixed(decimals);
}

Wie Sie sehen, musste ich ein wenig "Korrektur" hinzufügen (es ist nicht das, was es ist, aber da Math.round verlustbehaftet ist - Sie können es auf jsfiddle.net überprüfen - ist dies der einzige Weg, wie ich "reparieren" konnte "es). Es addiert 0,001 zu der bereits aufgefüllten Zahl, also fügt es 1drei 0s rechts vom Dezimalwert hinzu. Es sollte also sicher zu bedienen sein.

Danach habe ich hinzugefügt, .toFixed(decimal)um die Zahl immer im richtigen Format auszugeben (mit der richtigen Anzahl von Dezimalstellen).

Das war's auch schon. Benutze es gut;)

BEARBEITEN: Funktionalität zur "Korrektur" negativer Zahlen hinzugefügt.

tfrascaroli
quelle
2
Die "Korrektur" ist größtenteils sicher, gibt aber zB precise_round(1.27499,2)jetzt auch 1,28 zurück ... Es ist nicht Math.roundso verlustbehaftet; Computer speichern Gleitkommawerte intern. Grundsätzlich sind Sie dazu verdammt, mit einigen Werten zu scheitern, bevor die Daten überhaupt zu Ihrer Funktion gelangen :)
Imre
@ Imre, du hast absolut recht. Deshalb erkläre ich, was diese 0,001 dort macht, falls jemand sie " präziser " machen oder sogar löschen möchte (wenn Sie zufällig einen Supercomputer mit 2 MB pro Float haben, was meiner Meinung nach hier niemand tut ;)
tfrascaroli
1
Tatsächlich ist die Sprachspezifikation ziemlich spezifisch für die Verwendung von 64 Bit für Zahlenwerte, so dass ein Supercomputer nichts ändern würde :)
Imre
Für 0,001 können Sie ersetzen, indem Sie entsprechend der Länge der Dezimalstellen viele Nullen hinzufügen. also ..
Miguel
15

Eine Möglichkeit, 100% sicher zu sein, dass Sie eine Zahl mit 2 Dezimalstellen erhalten:

(Math.round(num*100)/100).toFixed(2)

Wenn dies zu Rundungsfehlern führt, können Sie Folgendes verwenden, wie James in seinem Kommentar erklärt hat:

(Math.round((num * 1000)/10)/100).toFixed(2)
Gerard de Visser
quelle
6
Dies ist der beste und einfachste Weg, dies zu tun. Aufgrund der Gleitkomma-Mathematik ist jedoch 1,275 * 100 = 127,49999999999999, was zu geringfügigen Fehlern bei der Rundung führen kann. Um dies zu beheben, können wir mit 1000 multiplizieren und durch 10 dividieren, als (1,275 * 1000) / 10 = 127,5. Wie folgt: var answer = (Math.round((num * 1000)/10)/100).toFixed(2);
James Gould
(Math.round ((1.015 * 1000) / 10) / 100) .toFixed (2) ergibt immer noch 1.01, sollte es nicht 1.02 sein?
Gaurav5430
14

toFixed (n) liefert n Länge nach dem Dezimalpunkt; toPrecision (x) liefert x Gesamtlänge.

Verwenden Sie diese Methode unten

// Example: toPrecision(4) when the number has 7 digits (3 before, 4 after)
    // It will round to the tenths place
    num = 500.2349;
    result = num.toPrecision(4); // result will equal 500.2

UND wenn Sie möchten, dass die Nummer fest verwendet wird

result = num.toFixed(2);
Syed Umar Ahmed
quelle
es funktioniert nicht gut ... für Nummer num = 50.2349 sollten Sie an Präzision (3) schreiben, um 50.2
Piotr Czyż
Es ist nur ein Beispiel, Sie können es nach Ihren Wünschen ändern @ PiotrCzyż
Syed Umar Ahmed
5

Ich habe keine genaue Lösung für dieses Problem gefunden und meine eigene erstellt:

function inprecise_round(value, decPlaces) {
  return Math.round(value*Math.pow(10,decPlaces))/Math.pow(10,decPlaces);
}

function precise_round(value, decPlaces){
    var val = value * Math.pow(10, decPlaces);
    var fraction = (Math.round((val-parseInt(val))*10)/10);

    //this line is for consistency with .NET Decimal.Round behavior
    // -342.055 => -342.06
    if(fraction == -0.5) fraction = -0.6;

    val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
    return val;
}

Beispiele:

function inprecise_round(value, decPlaces) {
  return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

function precise_round(value, decPlaces) {
  var val = value * Math.pow(10, decPlaces);
  var fraction = (Math.round((val - parseInt(val)) * 10) / 10);

  //this line is for consistency with .NET Decimal.Round behavior
  // -342.055 => -342.06
  if (fraction == -0.5) fraction = -0.6;

  val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
  return val;
}

// This may produce different results depending on the browser environment
console.log("342.055.toFixed(2)         :", 342.055.toFixed(2)); // 342.06 on Chrome & IE10

console.log("inprecise_round(342.055, 2):", inprecise_round(342.055, 2)); // 342.05
console.log("precise_round(342.055, 2)  :", precise_round(342.055, 2));   // 342.06
console.log("precise_round(-342.055, 2) :", precise_round(-342.055, 2));  // -342.06

console.log("inprecise_round(0.565, 2)  :", inprecise_round(0.565, 2));   // 0.56
console.log("precise_round(0.565, 2)    :", precise_round(0.565, 2));     // 0.57

Florian Ignaz Eßl
quelle
2
Vielen Dank. Hier ist ein Liedchen, um dies zu testen: jsfiddle.net/lamarant/ySXuF . Ich wende toFixed () auf den Wert an, bevor ich ihn zurückgebe, wodurch die korrekte Anzahl von Nullen an das Ende des zurückgegebenen Werts angehängt wird.
Lamarant
funktioniert nicht für Wert = 0,004990845956707237 und inprecise_round (Wert, 8) gibt 0,00499085 zurück, muss aber 0,00499084
MERT DOĞAN
3

@heridev und ich haben eine kleine Funktion in jQuery erstellt.

Sie können als nächstes versuchen:

HTML

<input type="text" name="one" class="two-digits"><br>
<input type="text" name="two" class="two-digits">​

jQuery

// apply the two-digits behaviour to elements with 'two-digits' as their class
$( function() {
    $('.two-digits').keyup(function(){
        if($(this).val().indexOf('.')!=-1){         
            if($(this).val().split(".")[1].length > 2){                
                if( isNaN( parseFloat( this.value ) ) ) return;
                this.value = parseFloat(this.value).toFixed(2);
            }  
         }            
         return this; //for chaining
    });
});

DEMO ONLINE:

http://jsfiddle.net/c4Wqn/

Vikmaster
quelle
1
Ich kann den Beitrag schätzen, obwohl ich denke, dass das Hinzufügen von DOM-Elementen und jQuery zum Mix nicht in den Rahmen der Frage fällt.
Chris 5.
Sie sollten das Keyup-Ereignis nicht abhören, da es sehr schlecht aussieht und nicht aktiviert wird, wenn Sie etwas mit einem Skript hinzufügen. Ich höre mir lieber die inputVeranstaltung an. Dies erzeugt keinen flackernden Effekt und wird auch ausgelöst, wenn Sie mit JS
Le 'nton
3

Das Problem mit Gleitkommawerten besteht darin, dass sie versuchen, eine unendliche Anzahl von (kontinuierlichen) Werten mit einer festen Anzahl von Bits darzustellen. Natürlich muss es einen Verlust im Spiel geben, und Sie werden mit einigen Werten gebissen.

Wenn ein Computer 1,275 als Gleitkommawert speichert, merkt er sich nicht, ob es 1,275 oder 1,27499999999999993 oder sogar 1,27500000000000002 war. Diese Werte sollten nach dem Runden auf zwei Dezimalstellen unterschiedliche Ergebnisse liefern, werden dies jedoch nicht, da sie für Computer nach dem Speichern als Gleitkommawerte genau gleich aussehen und es keine Möglichkeit gibt, die verlorenen Daten wiederherzustellen. Bei weiteren Berechnungen wird nur eine solche Ungenauigkeit akkumuliert.

Wenn es also auf Präzision ankommt, müssen Sie Gleitkommawerte von Anfang an vermeiden. Die einfachsten Möglichkeiten sind zu

  • Verwenden Sie eine dedizierte Bibliothek
  • Verwenden Sie Zeichenfolgen zum Speichern und Weitergeben der Werte (begleitet von Zeichenfolgenoperationen).
  • Verwenden Sie ganze Zahlen (z. B. könnten Sie den Betrag von Hundertstel Ihres tatsächlichen Werts herumgeben, z. B. den Betrag in Cent anstelle des Betrags in Dollar).

Wenn Sie beispielsweise Ganzzahlen zum Speichern der Anzahl der Hundertstel verwenden, ist die Funktion zum Ermitteln des tatsächlichen Werts recht einfach:

function descale(num, decimals) {
    var hasMinus = num < 0;
    var numString = Math.abs(num).toString();
    var precedingZeroes = '';
    for (var i = numString.length; i <= decimals; i++) {
        precedingZeroes += '0';
    }
    numString = precedingZeroes + numString;
    return (hasMinus ? '-' : '') 
        + numString.substr(0, numString.length-decimals) 
        + '.' 
        + numString.substr(numString.length-decimals);
}

alert(descale(127, 2));

Bei Strings müssen Sie runden, aber es ist immer noch überschaubar:

function precise_round(num, decimals) {
    var parts = num.split('.');
    var hasMinus = parts.length > 0 && parts[0].length > 0 && parts[0].charAt(0) == '-';
    var integralPart = parts.length == 0 ? '0' : (hasMinus ? parts[0].substr(1) : parts[0]);
    var decimalPart = parts.length > 1 ? parts[1] : '';
    if (decimalPart.length > decimals) {
        var roundOffNumber = decimalPart.charAt(decimals);
        decimalPart = decimalPart.substr(0, decimals);
        if ('56789'.indexOf(roundOffNumber) > -1) {
            var numbers = integralPart + decimalPart;
            var i = numbers.length;
            var trailingZeroes = '';
            var justOneAndTrailingZeroes = true;
            do {
                i--;
                var roundedNumber = '1234567890'.charAt(parseInt(numbers.charAt(i)));
                if (roundedNumber === '0') {
                    trailingZeroes += '0';
                } else {
                    numbers = numbers.substr(0, i) + roundedNumber + trailingZeroes;
                    justOneAndTrailingZeroes = false;
                    break;
                }
            } while (i > 0);
            if (justOneAndTrailingZeroes) {
                numbers = '1' + trailingZeroes;
            }
            integralPart = numbers.substr(0, numbers.length - decimals);
            decimalPart = numbers.substr(numbers.length - decimals);
        }
    } else {
        for (var i = decimalPart.length; i < decimals; i++) {
            decimalPart += '0';
        }
    }
    return (hasMinus ? '-' : '') + integralPart + (decimals > 0 ? '.' + decimalPart : '');
}

alert(precise_round('1.275', 2));
alert(precise_round('1.27499999999999993', 2));

Beachten Sie, dass diese Funktion auf den nächsten Wert rundet und von Null abweicht , während IEEE 754 empfiehlt, auf den nächsten Wert zu runden, der sogar als Standardverhalten für Gleitkommaoperationen verwendet wird. Solche Modifikationen bleiben dem Leser als Übung überlassen :)

Imre
quelle
3

Hier ist eine einfache

function roundFloat(num,dec){
    var d = 1;
    for (var i=0; i<dec; i++){
        d += "0";
    }
    return Math.round(num * d) / d;
}

Verwenden Sie wie alert(roundFloat(1.79209243929,4));

Jsfiddle

ow3n
quelle
2

Runden Sie Ihren Dezimalwert und verwenden Sie ihn dann toFixed(x)für Ihre erwartete (n) Ziffer (n).

function parseDecimalRoundAndFixed(num,dec){
  var d =  Math.pow(10,dec);
  return (Math.round(num * d) / d).toFixed(dec);
}

Anruf

parseDecimalRoundAndFixed (10.800243929,4) => 10.80 parseDecimalRoundAndFixed (10.807243929,2) => 10.81

HATCHA
quelle
2

Abrunden

function round_down(value, decPlaces) {
    return Math.floor(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Zusammenfassen

function round_up(value, decPlaces) {
    return Math.ceil(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Runde am nächsten

function round_nearest(value, decPlaces) {
    return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Zusammengeführtes https://stackoverflow.com/a/7641824/1889449 und https://www.kirupa.com/html5/rounding_numbers_in_javascript.htm Vielen Dank.

MERT DOĞAN
quelle
2

/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */

function RoundCorrect(num, precision = 2) {
	// half epsilon to correct edge cases.
	var c = 0.5 * Number.EPSILON * num;
//	var p = Math.pow(10, precision); //slow
	var p = 1; while (precision--> 0) p *= 10;
	if (num < 0)
		p *= -1;
	return Math.round((num + c) * p) / p;
}

// testing some +ve edge cases
console.log(RoundCorrect(1.005, 2));  // 1.01 correct
console.log(RoundCorrect(2.175, 2));  // 2.18 correct
console.log(RoundCorrect(5.015, 2));  // 5.02 correct

// testing some -ve edge cases
console.log(RoundCorrect(-1.005, 2));  // -1.01 correct
console.log(RoundCorrect(-2.175, 2));  // -2.18 correct
console.log(RoundCorrect(-5.015, 2));  // -5.02 correct

Amr Ali
quelle
2

Hier ist meine 1-Zeilen-Lösung: Number((yourNumericValueHere).toFixed(2));

Folgendes passiert:

1) Zuerst wenden Sie .toFixed(2)auf die Zahl an, deren Dezimalstellen abgerundet werden sollen. Beachten Sie, dass dadurch der Wert von number in eine Zeichenfolge konvertiert wird. Wenn Sie also Typescript verwenden, wird ein Fehler wie der folgende ausgegeben:

"Der Typ 'Zeichenfolge' kann nicht dem Typ 'Nummer' zugewiesen werden."

2) Um den numerischen Wert zurückzugewinnen oder den String in einen numerischen Wert umzuwandeln, wenden Sie einfach die Number()Funktion auf diesen sogenannten 'String'-Wert an.

Schauen Sie sich zur Verdeutlichung das folgende Beispiel an:

BEISPIEL: Ich habe einen Betrag mit bis zu 5 Nachkommastellen und möchte ihn auf bis zu 2 Dezimalstellen kürzen. Ich mache es so:

var price = 0.26453;
var priceRounded = Number((price).toFixed(2));
console.log('Original Price: ' + price);
console.log('Price Rounded: ' + priceRounded);

Devner
quelle
1

Stellen Sie Folgendes in einen globalen Bereich:

Number.prototype.getDecimals = function ( decDigCount ) {
   return this.toFixed(decDigCount);
}

und dann versuchen :

var a = 56.23232323;
a.getDecimals(2); // will return 56.23

Aktualisieren

Beachten Sie, dass toFixed()dies nur für die Anzahl der Dezimalstellen zwischen funktionieren kann, 0-20dh dass a.getDecimals(25)möglicherweise ein Javascript-Fehler generiert wird

Number.prototype.getDecimals = function ( decDigCount ) {
   return ( decDigCount > 20 ) ? this : this.toFixed(decDigCount);
}
Kamran Ahmed
quelle
1
Number(((Math.random() * 100) + 1).toFixed(2))

Dies gibt eine Zufallszahl von 1 bis 100 zurück, die auf 2 Dezimalstellen gerundet ist.

Johnathan Ralls
quelle
1

Verwenden dieser Antwort als Referenz: https://stackoverflow.com/a/21029698/454827

Ich baue eine Funktion, um dynamische Dezimalzahlen zu erhalten:

function toDec(num, dec)
{
        if(typeof dec=='undefined' || dec<0)
                dec = 2;

        var tmp = dec + 1;
        for(var i=1; i<=tmp; i++)
                num = num * 10;

        num = num / 10;
        num = Math.round(num);
        for(var i=1; i<=dec; i++)
                num = num / 10;

        num = num.toFixed(dec);

        return num;
}

hier Arbeitsbeispiel: https://jsfiddle.net/wpxLduLc/

ZiTAL
quelle
1

parse = function (data) {
       data = Math.round(data*Math.pow(10,2))/Math.pow(10,2);
       if (data != null) {
            var lastone = data.toString().split('').pop();
            if (lastone != '.') {
                 data = parseFloat(data);
            }
       }
       return data;
  };

$('#result').html(parse(200)); // output 200
$('#result1').html(parse(200.1)); // output 200.1
$('#result2').html(parse(200.10)); // output 200.1
$('#result3').html(parse(200.109)); // output 200.11
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="result"></div>
<div id="result1"></div>
<div id="result2"></div>
<div id="result3"></div>

Vishnu T Asok
quelle
1

Bei diesen Beispielen wird immer noch eine Fehlermeldung angezeigt, wenn Sie versuchen, die Zahl 1.005 zu runden. Die Lösung besteht darin, entweder eine Bibliothek wie Math.js oder diese Funktion zu verwenden:

function round(value: number, decimals: number) {
    return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}
David Webster
quelle
1

Ich habe vor ein paar Monaten einige Ideen aus diesem Beitrag erhalten, aber keine der Antworten hier oder Antworten aus anderen Beiträgen / Blogs konnten alle Szenarien verarbeiten (z. B. negative Zahlen und einige "Glückszahlen", die unser Tester gefunden hat). Am Ende fand unser Tester unten kein Problem mit dieser Methode. Einen Ausschnitt meines Codes einfügen:

fixPrecision: function (value) {
    var me = this,
        nan = isNaN(value),
        precision = me.decimalPrecision;

    if (nan || !value) {
        return nan ? '' : value;
    } else if (!me.allowDecimals || precision <= 0) {
        precision = 0;
    }

    //[1]
    //return parseFloat(Ext.Number.toFixed(parseFloat(value), precision));
    precision = precision || 0;
    var negMultiplier = value < 0 ? -1 : 1;

    //[2]
    var numWithExp = parseFloat(value + "e" + precision);
    var roundedNum = parseFloat(Math.round(Math.abs(numWithExp)) + 'e-' + precision) * negMultiplier;
    return parseFloat(roundedNum.toFixed(precision));
},

Ich habe auch Codekommentare (sorry, ich habe bereits alle Details vergessen) ... Ich poste meine Antwort hier als zukünftige Referenz:

9.995 * 100 = 999.4999999999999
Whereas 9.995e2 = 999.5
This discrepancy causes Math.round(9.995 * 100) = 999 instead of 1000.
Use e notation instead of multiplying /dividing by Math.Pow(10,precision).
remondo
quelle
0

Ich behebe das Problem mit dem Modifikator. Unterstützt nur 2 Dezimalstellen.

$(function(){
  //input number only.
  convertNumberFloatZero(22); // output : 22.00
  convertNumberFloatZero(22.5); // output : 22.50
  convertNumberFloatZero(22.55); // output : 22.55
  convertNumberFloatZero(22.556); // output : 22.56
  convertNumberFloatZero(22.555); // output : 22.55
  convertNumberFloatZero(22.5541); // output : 22.54
  convertNumberFloatZero(22222.5541); // output : 22,222.54

  function convertNumberFloatZero(number){
	if(!$.isNumeric(number)){
		return 'NaN';
	}
	var numberFloat = number.toFixed(3);
	var splitNumber = numberFloat.split(".");
	var cNumberFloat = number.toFixed(2);
	var cNsplitNumber = cNumberFloat.split(".");
	var lastChar = splitNumber[1].substr(splitNumber[1].length - 1);
	if(lastChar > 0 && lastChar < 5){
		cNsplitNumber[1]--;
	}
	return Number(splitNumber[0]).toLocaleString('en').concat('.').concat(cNsplitNumber[1]);
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

Bamossza
quelle
0
(Math.round((10.2)*100)/100).toFixed(2)

Das sollte ergeben: 10.20

(Math.round((.05)*100)/100).toFixed(2)

Das sollte ergeben: 0.05

(Math.round((4.04)*100)/100).toFixed(2)

Das sollte ergeben: 4.04

usw.

Anthony Ruffino
quelle
0

/*Due to all told stuff. You may do 2 things for different purposes:
When showing/printing stuff use this in your alert/innerHtml= contents:
YourRebelNumber.toFixed(2)*/

var aNumber=9242.16;
var YourRebelNumber=aNumber-9000;
alert(YourRebelNumber);
alert(YourRebelNumber.toFixed(2));

/*and when comparing use:
Number(YourRebelNumber.toFixed(2))*/

if(YourRebelNumber==242.16)alert("Not Rounded");
if(Number(YourRebelNumber.toFixed(2))==242.16)alert("Rounded");

/*Number will behave as you want in that moment. After that, it'll return to its defiance.
*/

Christian Læirbag
quelle
0

Dies ist sehr einfach und funktioniert genauso gut wie alle anderen:

function parseNumber(val, decimalPlaces) {
    if (decimalPlaces == null) decimalPlaces = 0
    var ret = Number(val).toFixed(decimalPlaces)
    return Number(ret)
}

Da toFixed () nur für Zahlen aufgerufen werden kann und leider eine Zeichenfolge zurückgibt, führt dies die gesamte Analyse für Sie in beide Richtungen durch. Sie können eine Zeichenfolge oder eine Nummer übergeben und erhalten jedes Mal eine Nummer zurück! Wenn Sie parseNumber (1.49) aufrufen, erhalten Sie 1 und parseNumber (1.49,2) 1,50. Genau wie die Besten!

Aaron Dake
quelle
0

Sie können auch die .toPrecision()Methode und einen benutzerdefinierten Code verwenden und unabhängig von der Länge des int-Teils immer auf die n-te Dezimalstelle aufrunden.

function glbfrmt (number, decimals, seperator) {
    return typeof number !== 'number' ? number : number.toPrecision( number.toString().split(seperator)[0].length + decimals);
}

Sie können es auch zu einem Plugin für eine bessere Verwendung machen.

leo_lo
quelle
-1

So einfach ist das.

var rounded_value=Math.round(value * 100) / 100;
Gihan Gamage
quelle
1
Falsch. Versuchen Sie 1.015
Marco Marsala
-2

Ich habe einen sehr einfachen Weg gefunden, der dieses Problem für mich gelöst hat und verwendet oder angepasst werden kann:

td[row].innerHTML = price.toPrecision(price.toFixed(decimals).length

quelle
-4

100% arbeiten !!! Versuch es

<html>
     <head>
      <script>
      function replacePonto(){
        var input = document.getElementById('qtd');
        var ponto = input.value.split('.').length;
        var slash = input.value.split('-').length;
        if (ponto > 2)
                input.value=input.value.substr(0,(input.value.length)-1);

        if(slash > 2)
                input.value=input.value.substr(0,(input.value.length)-1);

        input.value=input.value.replace(/[^0-9.-]/,'');

        if (ponto ==2)
	input.value=input.value.substr(0,(input.value.indexOf('.')+3));

if(input.value == '.')
	input.value = "";
              }
      </script>
      </head>
      <body>
         <input type="text" id="qtd" maxlength="10" style="width:140px" onkeyup="return replacePonto()">
      </body>
    </html>

JONAS MAGALHAES DOS SANTOS
quelle
Willkommen bei SO. Bitte lesen Sie diese How-to-Antwort und folgen Sie den Leitfaden zur Antwort.
thewaywewere