Risposte:
var result = Math.round(original*100)/100;
Le specifiche , nel caso in cui il codice non sia autoesplicativo.
modifica: ... o semplicemente usa toFixed, come proposto da Tim Büthe . Dimenticato quello, grazie (e un voto) per il promemoria :)
toFixed()imiterà ciò che printf()fa qualcosa di simile in C. Tuttavia, toFixed()e Math.round()gestirà l'arrotondamento in modo diverso. In questo caso, toFixed()avrà lo stesso tipo di effetto che Math.floor()avrebbe (garantito che stai moltiplicando in anticipo l'originale di 10 ^ n e chiamando toFixed()con n cifre). La "correttezza" della risposta dipende molto da ciò che l'OP vuole qui, ed entrambi sono "corretti" a modo loro.
Ci sono funzioni per arrotondare i numeri. Per esempio:
var x = 5.0364342423;
print(x.toFixed(2));
stamperà 5.04.
EDIT: violino
var x = 5.036432346; var y = x.toFixed(2) + 100; ysarà uguale"5.03100"
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
Fai attenzione quando usi toFixed():
Innanzitutto, l'arrotondamento del numero viene eseguito utilizzando la rappresentazione binaria del numero, che potrebbe portare a comportamenti imprevisti. Per esempio
(0.595).toFixed(2) === '0.59'
invece di '0.6'.
In secondo luogo, c'è un bug IE con toFixed(). In IE (almeno fino alla versione 7, non ho verificato IE8), vale quanto segue:
(0.9).toFixed(0) === '0'
Potrebbe essere una buona idea seguire il suggerimento di Kkyy o utilizzare una toFixed()funzione personalizzata , ad es
function toFixed(value, precision) {
var power = Math.pow(10, precision || 0);
return String(Math.round(value * power) / power);
}
.toFixed()metodo nativo nel valore restituito, che aggiungerà la quantità richiesta di precisione, ad esempio: return (Math.round(value * power) / power).toFixed(precision);e restituirà anche il valore come stringa. Altrimenti, la precisione di 20 viene ignorata per i decimali più piccoli
toFixed: nota che aumentare la precisione può produrre risultati inaspettati:, (1.2).toFixed(16) === "1.2000000000000000"mentre (1.2).toFixed(17) === "1.19999999999999996"(in Firefox / Chrome; in IE8 quest'ultimo non regge a causa della minore precisione che IE8 può offrire internamente).
(0.598).toFixed(2)non produce 0.6. Produce 0.60:)
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2).
Un altro problema da tenere presente è che toFixed()può produrre zeri non necessari alla fine del numero. Per esempio:
var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"
L'idea è di ripulire l'output usando un RegExp:
function humanize(x){
return x.toFixed(6).replace(/\.?0*$/,'');
}
Il RegExppartite le zeri finali (e facoltativamente il punto decimale) per assicurarsi che si guarda bene per gli interi pure.
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
C'è un problema con tutte quelle soluzioni che fluttuano intorno usando i moltiplicatori. Sfortunatamente sia la soluzione di Kkyy che quella di Christoph sono sbagliate.
Si prega di testare il codice per il numero 551.175 con 2 cifre decimali: arrotonderà a 551,17 mentre dovrebbe essere 551,18 ! Ma se provi per es. 451.175 andrà bene - 451.18. Quindi è difficile individuare questo errore a prima vista.
Il problema è con la moltiplicazione: prova 551.175 * 100 = 55117.49999999999 (aumenta!)
Quindi la mia idea è di trattarlo con toFixed () prima di usare Math.round ();
function roundFix(number, precision)
{
var multi = Math.pow(10, precision);
return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}
toFixedè anche influenzato - (0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)... Qualunque sia il metodo utilizzato, è meglio aggiungere un epsilon prima dell'arrotondamento.
La chiave qui credo sia di arrotondare prima correttamente, quindi puoi convertirla in String.
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
Ora puoi formattare in modo sicuro questo valore con toFixed (p). Quindi con il tuo caso specifico:
roundOf(0.3445434, 2).toFixed(2); // 0.34
Se vuoi la stringa senza giro puoi usare questo RegEx (forse non è il modo più efficiente ... ma è davvero facile)
(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;altrimenti se hai superato Integer, è tornato il numero con un punto alla fine (ad esempio ingresso: 2100, uscita: 2100.)
Forse vorrai anche un separatore decimale? Ecco una funzione che ho appena fatto:
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;
}
Non è possibile evitare arrotondamenti incoerenti per i prezzi con x.xx5 come valore effettivo utilizzando la moltiplicazione o la divisione. Se è necessario calcolare i prezzi corretti sul lato client, è necessario conservare tutti gli importi in centesimi. Ciò è dovuto alla natura della rappresentazione interna dei valori numerici in JavaScript. Si noti che Excel soffre degli stessi problemi, quindi la maggior parte delle persone non noterebbe i piccoli errori causati da questo fenomeno. Tuttavia, gli errori possono accumularsi ogni volta che si sommano molti valori calcolati, c'è un'intera teoria attorno a ciò che coinvolge l'ordine dei calcoli e altri metodi per minimizzare l'errore nel risultato finale. Per enfatizzare i problemi con i valori decimali, si noti che 0,1 + 0,2 non è esattamente uguale a 0,3 in JavaScript, mentre 1 + 2 è uguale a 3.
/** 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"
Uso questo codice per formattare i float. Si basa su toPrecision()ma elimina gli zeri non necessari. Gradirei suggerimenti su come semplificare la regex.
function round(x, n) {
var exp = Math.pow(10, n);
return Math.floor(x*exp + 0.5)/exp;
}
Esempio di utilizzo:
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>');