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.