JavaScript: arrotondare a un numero di cifre decimali, ma rimuovere gli zeri aggiuntivi


85

Ecco lo scenario: sto ottenendo .9999999999999999quando dovrei ottenere 1.0.
Posso permettermi di perdere una cifra decimale di precisione, quindi sto usando .toFixed(15), quale tipo di lavoro.

L'arrotondamento funziona, ma il problema è che mi viene dato 1.000000000000000.
C'è un modo per arrotondare a un numero di cifre decimali, ma rimuovere gli spazi bianchi extra?

Nota: .toPrecisionnon è quello che voglio; Voglio solo specificare quanti numeri dopo il punto decimale.
Nota 2: non posso usarlo solo .toPrecision(1)perché ho bisogno di mantenere l'alta precisione per i numeri che hanno effettivamente dati dopo il punto decimale. Idealmente, ci sarebbero esattamente tutte le cifre decimali necessarie (fino a 15).


Il punto è che .toFixed restituisce una stringa, quindi semplicemente eseguendo il round trip tramite un numero e quindi di nuovo in una stringa lo riconvertirà senza gli zeri finali.
Neil

@ Nathan: solo per chiarimenti. Vuoi solo rimuovere gli zeri finali nella stringa che hai ottenuto con toFixed ()?
Jiri Kriz

Risposte:


141
>>> parseFloat(0.9999999.toFixed(4));
1
>>> parseFloat(0.0009999999.toFixed(4));
0.001
>>> parseFloat(0.0000009999999.toFixed(4));
0

4
Non dimenticare di metterli tra parentesi quando tratti i numeri negativi: -2.34.toFixed(1)restituisce a -2.3causa della precedenza dell'operatore .
Константин Ван

1
L'utilizzo dell'operatore unario + dovrebbe essere più veloce della parseFloatfunzione: +number.toFixed(13)questa espressione può essere utilizzata anche per rimuovere le imprecisioni del numero JavaScript come in 1.0000000000000045.
ygoe


19

Come ho capito, vuoi rimuovere gli zeri finali nella stringa che hai ottenuto tramite toFixed(). Questa è una pura operazione di stringa:

var x = 1.1230000;
var y = x.toFixed(15).replace(/0+$/, "");  // ==> 1.123

6
Sei l'unico che ha davvero risposto alla domanda .. grazie!
Mugen

4
Questo lascia il punto sui numeri tondi ("100.00" => "100.")
pckill

5
@pckill se non vuoi che il punto lo puoi includere nell'espressione regolare da sostituire ( ...replace(/\.?0+$/, "");).
Zach Snow

Questo fallisce su 0 e -0 perché 0diventa la stringa vuota ""e -0diventa -, nessuno dei quali è previsto (a caso). @ zach-snow la tua soluzione suggerita fallisce anche su 0 e -0.
robocat

@ Mugen, qual era il problema con la risposta di Gus?
trysis

10

Number(n.toFixed(15)) or +(n.toFixed(15)) convertirà la stringa decimale di 15 cifre in un numero, rimuovendo gli zeri finali.


1
Ho pensato di farlo notare, + (n.toFixed (...)) è molto più efficiente di parseFloat. Non sono sicuro del perché, ma è anche più efficiente di Number in Chrome.
Domino

8

Se esegui il cast del valore restituito su un numero, gli zeri finali verranno eliminati. Questo è anche meno prolisso di quanto non lo parseFloat()sia.

+(4.55555).toFixed(2);
//-> 4.56

+(4).toFixed(2);
//-> 4

Questo utilizza l' operatore unario + , quindi se si utilizza questo come parte di un'operazione di stringa è necessario disporre di un infisso + prima che: var n=0.9999999999999999; console.log('output ' + +n.toFixed(2));. Cordiali saluti, un unario + davanti a una stringa lo converte in un numero. Da MDN: Unary + può:

converte le rappresentazioni di stringa di numeri interi e float, nonché i valori non di stringa true, false e null. Sono supportati numeri interi sia in formato decimale che esadecimale (con prefisso "0x"). I numeri negativi sono supportati (sebbene non per esadecimale). Se non è in grado di analizzare un valore particolare, restituirà NaN.


@robocat ho appena fatto un semplice controllo; +(4.1).toFixed(4)è 4.1in Chrome 60 .
Константин Ван

Non lo capisco. Qual è stato il motivo per cui questa risposta è stata sottovalutata?
Константин Ван

@K Avevi ragione, quindi ho cancellato il mio commento precedente e aggiunto alla risposta (penso che stavo usando infisso + con una stringa su lhs, piuttosto che usare correttamente unario +. Di solito sono più attento! Saluti)
robocat

Questa risposta funziona ancora con NaN, Infinity, -Infinity, 3e30 e 0. Alcune altre risposte falliscono in alcuni casi d'angolo.
robocat

(4) .toFixed (2) -> "4.00" in Chrome 60.0.3112.113
Daniel Que,

1

Nessuno di questi mi ha davvero ottenuto quello che stavo cercando in base al titolo della domanda, che era, ad esempio, 5.00 per 5 e 5.10 per 5.1. La mia soluzione era la seguente:

num.toFixed(places).replace(/\.?0+$/, '')

'5.00'.replace(/\.?0+$/, '') // 5
'5.10'.replace(/\.?0+$/, '') // 5.1
'5.0000001'.replace(/\.?0+$/, '') // 5.0000001
'5.0001000'.replace(/\.?0+$/, '') // 5.0001

Nota: la regex funziona solo se places > 0

PS https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed


Non riesce 5e30(cambia il numero in 5e3). I casi d'angolo sono diabolici!
robocat

0

C'è un metodo migliore che mantiene la precisione e rimuove anche gli zeri. Questo richiede un numero di input e attraverso la magia del casting tirerà fuori gli zeri finali. Ho scoperto che 16 è il limite di precisione per me, il che è abbastanza buono se non dovessi mettere un satellite su Plutone.

function convertToFixed(inputnum)
{

      var mynum = inputnum.toPrecision(16);
//If you have a string already ignore this first line and change mynum.toString to the inputnum

      var mynumstr = mynum.toString();
    return parseFloat(mynumstr);
    }
    alert(convertToFixed(6.6/6));

0

Il toFixed()metodo formatta a numberutilizzando la notazione a virgola fissa e restituisce a string.

Applica una strategia di arrotondamento a metà .

(0.124).toFixed(2); // returns 0.12
(0.125).toFixed(2); // returns 0.13

Come hai descritto, a volte si tradurrà anche in zero finali (potenzialmente non necessari).

(0.001).toFixed(2); // returns 0.00

Potresti non voler sbarazzarti di quegli zeri finali, essenzialmente potresti semplicemente riconvertirlo in un file number. Ci sono molti modi per farlo.

+(0.001).toFixed(2); // the shortest

Per una panoramica dei diversi metodi per convertire le stringhe in numeri, controlla questa domanda, che ha alcune risposte eccellenti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.