Come formattare un float in javascript?

In JavaScript, quando si converte da un float in una stringa, come posso ottenere solo 2 cifre dopo il punto decimale? Ad esempio, 0,34 anziché 0,3445434.

Ci sono funzioni per arrotondare i numeri. Per esempio:

 var x = 5.0364342423; print(x.toFixed(2)); 

stamperà 5.04.

EDIT: Fiddle

toFixed() attenzione quando usi toFixed() :

Innanzitutto, l’arrotondamento del numero viene eseguito utilizzando la rappresentazione binaria del numero, che potrebbe comportare un comportamento imprevisto. Per esempio

 (0.595).toFixed(2) === '0.59' 

invece di '0.6' .

Secondo, c’è un bug di IE con toFixed() . In IE (almeno fino alla versione 7, non ho verificato IE8), è vero quanto segue:

 (0.9).toFixed(0) === '0' 

Potrebbe essere una buona idea seguire il suggerimento di kkyy o usare una funzione personalizzata toFixed() , ad es

 function toFixed(value, precision) { var power = Math.pow(10, precision || 0); return String(Math.round(value * power) / power); } 

Un altro problema di cui essere a conoscenza, è 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 utilizzando un RegExp :

 function humanize(x){ return x.toFixed(6).replace(/\.?0*$/,''); } 

RegExp corrisponde agli zeri finali (e facoltativamente al punto decimale) per assicurarsi che appaia anche per gli interi.

 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 

Probabilmente questo problema merita una risposta in più: come menzionato da Dony e ArteQ, l’arrotondamento è influenzato da una perdita di precisione (ovvero 0.5 può diventare 0.49999 …). La conseguenza è che l’arrotondamento non è né mezzo alto né mezzo basso , né alcun altro metodo di arrotondamento coerente, e fornirà risultati incoerenti indipendentemente dal metodo utilizzato.

In effetti anche toFixed è interessato:

 (0.335).toFixed(2) == 0.34 (0.345).toFixed(2) == 0.34 

Quindi, qualunque sia il metodo che usi, se hai bisogno di coerenza nell’arrotondamento è meglio aggiungere (o rimuovere) un epsilon.

Ad esempio per arrotondare a metà usando toFixed :

 var epsilon = 0.001; (0.335 + epsilon).toFixed(2) == 0.34; (0.345 + epsilon).toFixed(2) == 0.35; 

È lo stesso se costruisci la tua funzione, aggiungi / rimuovi un epsilon prima del calcolo.

Aggiornare :

Come sottolineato da Matias, questo metodo ha un difetto: qualunque sia il valore di epsilon, 0.334999999 … sarà sempre arrotondato a 0,34 anziché a 0,35. Quindi abbiamo coerenza, ma non “arrotondamenti standard”.

C’è un problema con tutte quelle soluzioni che fluttuano usando i moltiplicatori. Sfortunatamente, entrambe le soluzioni di Kicky e Christoph sono errate.

Si prega di testare il codice per il numero 551.175 con 2 cifre decimali – si arrotonderà a 551,17 mentre dovrebbe essere 551,18 ! Ma se provi per l’ex. 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 (ups!)

Quindi la mia idea è trattarla 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; } 

La chiave qui credo sarà di arrotondare correttamente prima, quindi è ansible convertirlo in stringa.

 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 tranquillamente formattare questo valore con toFixed (p). Quindi con il tuo caso specifico:

 roundOf(0.3445434, 2).toFixed(2); // 0.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; } 

Forse vorresti anche il 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 esiste alcun modo per evitare arrotondamenti incoerenti per i prezzi con x.xx5 come valore effettivo utilizzando la moltiplicazione o la divisione. Se è necessario calcolare i prezzi corretti 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 molte persone non noterebbero i piccoli errori causati da questo fenomeno. Tuttavia, gli errori possono accumularsi ogni volta che si sumno molti valori calcolati, c’è una teoria completa intorno a questo 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((ae)*nbDec); if (d == nbDec) { d=0; e++; } var signStr = (x<0) ? "-" : " "; var decStr = d.toString(); var tmp = 10; while(tmp 

Io uso questo codice per formattare i float. È basato su toPrecision() ma elimina gli zeri non necessari. Vorrei ricevere 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' + '
'); document.write(test(1.2000e+45, 3, 2) + '=' + '1.2e45' + '
'); document.write(test(1.2340e45, 3, 2) + '=' + '1.23e45' + '
'); document.write(test(1.2350e45, 3, 2) + '=' + '1.24e45' + '
'); document.write(test(1.0000, 3, 2) + '=' + '1' + '
'); document.write(test(1.0100, 3, 2) + '=' + '1.01' + '
'); document.write(test(1.2340, 4, 2) + '=' + '1.23' + '
'); document.write(test(1.2350, 4, 2) + '=' + '1.24' + '
');
  You can try this if you want don't want to use rounding 
  function myFunction() { var str = 12.234556; str = str.toString().split('.'); var res = str[1].slice(0, 2); document.getElementById("demo").innerHTML = str[0]+'.'+res; } output:12.23 

str.toString().split('.') convertirà il tuo numero float in stringa, quindi lo dividerà con ‘.’

Le variabili risultanti saranno una matrice con due elementi di tipo stringa, il primo elemento sarà 12 e il secondo elemento sarà 234556

str[1].slice(0, 2) divide la tua seconda (234556) stringa in primi due caratteri che sono 23

Quindi basta concatenare la prima e la stringa risultante attraverso str[0]+'.'+res

Spero che questo ti sia d’aiuto