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;
y
sarà 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 RegExp
partite 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>');