Wie kann ich in JavaScript beim Konvertieren von einem Float in einen String nur zwei Stellen nach dem Dezimalpunkt erhalten? Zum Beispiel 0,34 anstelle von 0,3445434.
Wie kann ich in JavaScript beim Konvertieren von einem Float in einen String nur zwei Stellen nach dem Dezimalpunkt erhalten? Zum Beispiel 0,34 anstelle von 0,3445434.
Antworten:
var result = Math.round(original*100)/100;
Die Einzelheiten , falls der Code nicht selbsterklärend ist.
edit: ... oder einfach benutzen toFixed
, wie von Tim Büthe vorgeschlagen . Ich habe das vergessen, danke (und eine positive Bewertung) für die Erinnerung :)
toFixed()
ahmt nach, was so etwas printf()
in C macht, toFixed()
und Math.round()
behandelt das Runden anders. In diesem Fall hat toFixed()
dies den gleichen Effekt Math.floor()
(vorausgesetzt, Sie multiplizieren das Original vorher mit 10 ^ n und rufen toFixed()
mit n Ziffern auf). Die "Richtigkeit" der Antwort hängt sehr davon ab, was das OP hier will, und beide sind auf ihre Weise "richtig".
Es gibt Funktionen zum Runden von Zahlen. Zum Beispiel:
var x = 5.0364342423;
print(x.toFixed(2));
druckt 5.04.
EDIT: Geige
var x = 5.036432346; var y = x.toFixed(2) + 100;
y
wird gleich sein"5.03100"
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
Seien Sie vorsichtig bei der Verwendung von toFixed()
:
Zunächst wird die Zahl mit der binären Darstellung der Zahl gerundet, was zu unerwartetem Verhalten führen kann. Zum Beispiel
(0.595).toFixed(2) === '0.59'
statt '0.6'
.
Zweitens gibt es einen IE-Fehler mit toFixed()
. Im IE (zumindest bis Version 7, IE8 wurde nicht überprüft) gilt Folgendes:
(0.9).toFixed(0) === '0'
Es könnte eine gute Idee sein, dem Vorschlag von kkyy zu folgen oder eine benutzerdefinierte toFixed()
Funktion zu verwenden, z
function toFixed(value, precision) {
var power = Math.pow(10, precision || 0);
return String(Math.round(value * power) / power);
}
.toFixed()
Methode zum Rückgabewert hinzuzufügen, wodurch die erforderliche Genauigkeit hinzugefügt wird, z. B.: return (Math.round(value * power) / power).toFixed(precision);
Und der Wert auch als Zeichenfolge zurückgegeben wird. Andernfalls wird eine Genauigkeit von 20 für kleinere Dezimalstellen ignoriert
toFixed
: Beachten Sie, dass das Erhöhen der Genauigkeit zu unerwarteten Ergebnissen führen kann : (1.2).toFixed(16) === "1.2000000000000000"
, während (1.2).toFixed(17) === "1.19999999999999996"
(in Firefox / Chrome; in IE8 gilt letzteres aufgrund der geringeren Genauigkeit, die IE8 intern bieten kann, nicht).
(0.598).toFixed(2)
nicht produziert 0.6
. Es produziert 0.60
:)
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
.
Ein weiteres zu beachtendes Problem besteht darin, dass toFixed()
am Ende der Zahl unnötige Nullen erzeugt werden können. Zum Beispiel:
var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"
Die Idee ist, die Ausgabe mit einem zu bereinigen RegExp
:
function humanize(x){
return x.toFixed(6).replace(/\.?0*$/,'');
}
Das RegExp
entspricht den nachgestellten Nullen (und optional dem Dezimalpunkt), um sicherzustellen, dass es auch für Ganzzahlen gut aussieht.
humanize(23-7.37)
"15.63"
humanize(1200)
"1200"
humanize(1200.03)
"1200.03"
humanize(3/4)
"0.75"
humanize(4/3)
"1.333333"
var x = 0.3445434
x = Math.round (x*100) / 100 // this will make nice rounding
Es gibt ein Problem mit all diesen Lösungen, die mit Multiplikatoren herumschwirren. Die Lösungen von kkyy und Christoph sind leider falsch.
Bitte testen Sie Ihren Code für die Nummer 551.175 mit 2 Dezimalstellen - er wird auf 551.17 gerundet, während er 551.18 sein sollte ! Aber wenn Sie zum Beispiel testen. 451.175 wird es in Ordnung sein - 451.18. Daher ist es schwierig, diesen Fehler auf den ersten Blick zu erkennen.
Das Problem liegt in der Multiplikation: Versuchen Sie es mit 551.175 * 100 = 55117.49999999999 (ups!)
Meine Idee ist es also, es mit toFixed () zu behandeln, bevor ich Math.round () verwende.
function roundFix(number, precision)
{
var multi = Math.pow(10, precision);
return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}
toFixed
betroffen - (0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
… Welche Methode auch immer verwendet wird, fügen Sie vor der Rundung besser ein Epsilon hinzu.
Der Schlüssel hier ist wohl, zuerst richtig aufzurunden, dann können Sie ihn in String konvertieren.
function roundOf(n, p) {
const n1 = n * Math.pow(10, p + 1);
const n2 = Math.floor(n1 / 10);
if (n1 >= (n2 * 10 + 5)) {
return (n2 + 1) / Math.pow(10, p);
}
return n2 / Math.pow(10, p);
}
// All edge cases listed in this thread
roundOf(95.345, 2); // 95.35
roundOf(95.344, 2); // 95.34
roundOf(5.0364342423, 2); // 5.04
roundOf(0.595, 2); // 0.60
roundOf(0.335, 2); // 0.34
roundOf(0.345, 2); // 0.35
roundOf(551.175, 2); // 551.18
roundOf(0.3445434, 2); // 0.34
Jetzt können Sie diesen Wert sicher mit toFixed (p) formatieren. Also mit Ihrem speziellen Fall:
roundOf(0.3445434, 2).toFixed(2); // 0.34
Wenn Sie die Zeichenfolge ohne Runde möchten, können Sie diese RegEx verwenden (vielleicht ist dies nicht der effizienteste Weg ... aber es ist wirklich einfach).
(2.34567778).toString().match(/\d+\.\d{2}/)[0]
// '2.34'
function trimNumber(num, len) {
const modulu_one = 1;
const start_numbers_float=2;
var int_part = Math.trunc(num);
var float_part = String(num % modulu_one);
float_part = float_part.slice(start_numbers_float, start_numbers_float+len);
return int_part+'.'+float_part;
}
return float_part ? int_part+'.'+float_part : int_part;
sonst , wenn Sie Integer übergeben, es zurück Zahl mit einem Punkt am Ende (zB Eingang: 2100
, Ausgang: 2100.
)
Vielleicht möchten Sie auch ein Dezimaltrennzeichen? Hier ist eine Funktion, die ich gerade gemacht habe:
function formatFloat(num,casasDec,sepDecimal,sepMilhar) {
if (num < 0)
{
num = -num;
sinal = -1;
} else
sinal = 1;
var resposta = "";
var part = "";
if (num != Math.floor(num)) // decimal values present
{
part = Math.round((num-Math.floor(num))*Math.pow(10,casasDec)).toString(); // transforms decimal part into integer (rounded)
while (part.length < casasDec)
part = '0'+part;
if (casasDec > 0)
{
resposta = sepDecimal+part;
num = Math.floor(num);
} else
num = Math.round(num);
} // end of decimal part
while (num > 0) // integer part
{
part = (num - Math.floor(num/1000)*1000).toString(); // part = three less significant digits
num = Math.floor(num/1000);
if (num > 0)
while (part.length < 3) // 123.023.123 if sepMilhar = '.'
part = '0'+part; // 023
resposta = part+resposta;
if (num > 0)
resposta = sepMilhar+resposta;
}
if (sinal < 0)
resposta = '-'+resposta;
return resposta;
}
Es gibt keine Möglichkeit, eine inkonsistente Rundung von Preisen mit x.xx5 als tatsächlichem Wert durch Multiplikation oder Division zu vermeiden. Wenn Sie auf Kundenseite die richtigen Preise berechnen müssen, sollten Sie alle Beträge in Cent aufbewahren. Dies liegt an der Art der internen Darstellung numerischer Werte in JavaScript. Beachten Sie, dass Excel unter denselben Problemen leidet, sodass die meisten Benutzer die kleinen Fehler, die durch dieses Phänomen verursacht werden, nicht bemerken würden. Obwohl sich Fehler ansammeln können, wenn Sie viele berechnete Werte addieren, gibt es eine ganze Theorie, die die Reihenfolge der Berechnungen und andere Methoden zur Minimierung des Fehlers im Endergebnis beinhaltet. Um die Probleme mit Dezimalwerten hervorzuheben, beachten Sie bitte, dass 0,1 + 0,2 in JavaScript nicht genau gleich 0,3 ist, während 1 + 2 gleich 3 ist.
/** don't spend 5 minutes, use my code **/
function prettyFloat(x,nbDec) {
if (!nbDec) nbDec = 100;
var a = Math.abs(x);
var e = Math.floor(a);
var d = Math.round((a-e)*nbDec); if (d == nbDec) { d=0; e++; }
var signStr = (x<0) ? "-" : " ";
var decStr = d.toString(); var tmp = 10; while(tmp<nbDec && d*tmp < nbDec) {decStr = "0"+decStr; tmp*=10;}
var eStr = e.toString();
return signStr+eStr+"."+decStr;
}
prettyFloat(0); // "0.00"
prettyFloat(-1); // "-1.00"
prettyFloat(-0.999); // "-1.00"
prettyFloat(0.5); // "0.50"
Ich benutze diesen Code, um Floats zu formatieren. Es basiert auf, entfernt toPrecision()
aber unnötige Nullen. Ich würde Vorschläge zur Vereinfachung der Regex begrüßen.
function round(x, n) {
var exp = Math.pow(10, n);
return Math.floor(x*exp + 0.5)/exp;
}
Anwendungsbeispiel:
function test(x, n, d) {
var rounded = rnd(x, d);
var result = rounded.toPrecision(n);
result = result.replace(/\.?0*$/, '');
result = result.replace(/\.?0*e/, 'e');
result = result.replace('e+', 'e');
return result;
}
document.write(test(1.2000e45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2000e+45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2340e45, 3, 2) + '=' + '1.23e45' + '<br>');
document.write(test(1.2350e45, 3, 2) + '=' + '1.24e45' + '<br>');
document.write(test(1.0000, 3, 2) + '=' + '1' + '<br>');
document.write(test(1.0100, 3, 2) + '=' + '1.01' + '<br>');
document.write(test(1.2340, 4, 2) + '=' + '1.23' + '<br>');
document.write(test(1.2350, 4, 2) + '=' + '1.24' + '<br>');