Mi sto perdendo qualcosa qui?
var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string
Perché non.toFixed()restituire una stringa?
Voglio arrotondare il numero a 2 cifre decimali.
Mi sto perdendo qualcosa qui?
var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string
Perché non.toFixed()restituire una stringa?
Voglio arrotondare il numero a 2 cifre decimali.
Risposte:
Restituisce una stringa perché 0.1, e i suoi poteri (che sono usati per visualizzare le frazioni decimali), non sono rappresentabili (almeno non con la massima precisione) nei sistemi binari a virgola mobile.
Ad esempio, 0,1 è davvero 0,1000000000000000055511151231257827021181583404541015625 e 0,01 è davvero 0,010000000000000000008868681711721685132943093776702880859375. (Grazie per BigDecimalaver dimostrato il mio punto. :-P)
Pertanto (in assenza di un virgola mobile decimale o di un tipo di numero razionale), emetterlo come una stringa è l'unico modo per farlo tagliare esattamente alla precisione richiesta per la visualizzazione.
toFixedè una funzione di formattazione, che ha il solo scopo di convertire un numero in una stringa, formattandolo utilizzando il numero specificato di decimali. Il motivo per cui restituisce una stringa è perché dovrebbe restituire una stringa e se invece fosse stata nominata toStringFixed, OP non sarebbe sorpreso dai risultati. L'unico problema qui è che OP si aspettava che funzionasse come Math.round, senza consultare il riferimento JS.
Number.prototype.toFixedè una funzione progettata per formattare un numero prima di stamparlo. Viene dalla famiglia di toString, toExponentiale toPrecision.
Per arrotondare un numero, devi fare questo:
someNumber = 42.008;
someNumber = Math.round( someNumber * 1e2 ) / 1e2;
someNumber === 42.01;
// if you need 3 digits, replace 1e2 with 1e3 etc.
// or just copypaste this function to your code:
function toFixedNumber(num, digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(num*pow) / pow;
}
.
Oppure, se si desidera una funzione " simile al nativo ", è possibile estendere il prototipo:
Number.prototype.toFixedNumber = function(digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(this*pow) / pow;
}
someNumber = 42.008;
someNumber = someNumber.toFixedNumber(2);
someNumber === 42.01;
//or even hexadecimal
someNumber = 0xAF309/256 //which is af3.09
someNumber = someNumber.toFixedNumber(1, 16);
someNumber.toString(16) === "af3.1";
Tuttavia , tenere presente che l'inquinamento del prototipo è considerato negativo quando si scrive un modulo, poiché i moduli non dovrebbero avere effetti collaterali. Quindi, per un modulo, utilizzare la prima funzione .
type Number. Il fatto è che +(anyValue)restituisce sempre un numero, ad es. +("45")ritorna 45, +(new Number(42))ritorna 42. È un po 'come scrivere forte la funzione. Se ne
someNumber = Math.round( 42.008 * 1e2 ) / 1e2;non 42.01lo è, lo è ~42.0099999999999980. Motivo: il numero 42.01non esiste e viene arrotondato al numero esistente più vicino. tra l'altro, prova i numeri toPrecision(18)per stamparlo con tutte le cifre rilevanti.
Ho risolto questo problema modificandolo:
someNumber = someNumber.toFixed(2)
...a questa:
someNumber = +someNumber.toFixed(2);
Tuttavia, questo convertirà il numero in una stringa e lo analizzerà di nuovo, il che avrà un impatto significativo sulle prestazioni. Se ti interessano le prestazioni o la sicurezza dei tipi, controlla anche le altre risposte.
someNumber = Math.round(someNumber * 1e2) / 1e2! Vedi la mia risposta per un modo più generalizzato.
Perché non usare parseFloat?
var someNumber = 123.456;
someNumber = parseFloat(someNumber.toFixed(2));
alert(typeof(someNumber));
//alerts number
Ovviamente restituisce una stringa. Se si desidera arrotondare la variabile numerica, utilizzare invece Math.round (). Il punto di Fisso è formattare il numero con un numero fisso di posizioni decimali da visualizzare all'utente .
Cosa ti aspetteresti che ritorni quando dovrebbe formattare un numero? Se hai un numero, non puoi praticamente farci nulla, ad es 2 == 2.0 == 2.00. Ecc., Quindi deve essere una stringa.
Per fornire un esempio del motivo per cui deve essere una stringa:
Se formatti 1.toFixed (2) otterrai '1.00'.
Questo non è uguale a 1, in quanto 1 non ha 2 decimali.
So che JavaScript non è esattamente un linguaggio delle prestazioni , ma è probabile che otterrai prestazioni migliori per un arrotondamento se usi qualcosa come: arrotondatoValore = Math.round (valore * 100) * 0,01
Perché il suo uso principale è la visualizzazione di numeri? Se si desidera arrotondare i numeri, utilizzare Math.round()con fattori appropriati.
'42'è un numero ... che non lo è. Solo perché una stringa contiene solo cifre non la rende un numero. Questo non è PHP. :-P
Ecco una versione leggermente più funzionale della risposta m93afornita.
const toFixedNumber = (toFixTo = 2, base = 10) => num => {
const pow = Math.pow(base, toFixTo)
return +(Math.round(num * pow) / pow)
}
const oneNumber = 10.12323223
const result1 = toFixedNumber(2)(oneNumber) // 10.12
const result2 = toFixedNumber(3)(oneNumber) // 10.123
// or using pipeline-operator
const result3 = oneNumber |> toFixedNumber(2) // 10.12