Estou faltando alguma coisa aqui?
var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string
Por que.toFixed()
retornar uma string?
Quero arredondar o número para 2 dígitos decimais.
Estou faltando alguma coisa aqui?
var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string
Por que.toFixed()
retornar uma string?
Quero arredondar o número para 2 dígitos decimais.
Respostas:
Ele retorna uma string porque 0,1 e suas potências (que são usadas para exibir frações decimais) não são representáveis (pelo menos não com precisão total) em sistemas binários de ponto flutuante.
Por exemplo, 0.1 é realmente 0.1000000000000000055511151231257827021181583404541015625 e 0.01 é realmente 0.01000000000000000020816681711721685132943093776702880859375. (Obrigado BigDecimal
por provar meu ponto. :-P)
Portanto (sem um ponto flutuante decimal ou um tipo de número racional), a saída como uma sequência é a única maneira de ajustá-lo exatamente à precisão necessária para a exibição.
toFixed
é uma função de formatação, que tem o único objetivo de converter um número em uma sequência de caracteres, formatando-o usando o número especificado de casas decimais. O motivo pelo qual ele retorna uma sequência é porque ela deve retornar uma sequência e, se fosse nomeada toStringFixed
, o OP não ficaria surpreso com os resultados. O único problema aqui é que o OP esperava que funcionasse como Math.round
, sem consultar a referência JS.
Number.prototype.toFixed
é uma função projetada para formatar um número antes de imprimi-lo. É da família de toString
, toExponential
e toPrecision
.
Para arredondar um número, você faria o seguinte:
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;
}
.
Ou, se você deseja uma função " nativa ", pode estender o protótipo:
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";
No entanto , lembre-se de que poluir o protótipo é considerado ruim quando você está escrevendo um módulo, pois os módulos não devem ter efeitos colaterais. Portanto, para um módulo, use a primeira função .
type Number
. A coisa é que +(anyValue)
sempre retorna um número - por exemplo. +("45")
retorna 45
, +(new Number(42))
retorna 42
. É como digitar com força a função. Se você fizer disso um hábito, você pode evitar um monte de erros :)
someNumber = Math.round( 42.008 * 1e2 ) / 1e2;
não é 42.01
, é ~42.0099999999999980
. Motivo: o número 42.01
não existe e é arredondado para o número existente mais próximo. entre, números de prova por toPrecision(18)
para imprimi-lo com todos os dígitos relevantes.
Eu resolvi esse problema alterando isso:
someNumber = someNumber.toFixed(2)
...para isso:
someNumber = +someNumber.toFixed(2);
No entanto, isso converterá o número em uma sequência e o analisará novamente, o que terá um impacto significativo no desempenho. Se você se preocupa com desempenho ou segurança de tipo, verifique as outras respostas também.
someNumber = Math.round(someNumber * 1e2) / 1e2
! Veja minha resposta para uma maneira mais generalizada.
Por que não usar parseFloat
?
var someNumber = 123.456;
someNumber = parseFloat(someNumber.toFixed(2));
alert(typeof(someNumber));
//alerts number
Claro que retorna uma string. Se você quiser arredondar a variável numérica, use Math.round (). O ponto de toFixed é formatar o número com um número fixo de casas decimais para exibição no usuário .
O que você esperaria que retornasse quando deveria formatar um número? Se você tem um número, não pode fazer nada com ele porque, por exemplo, 2 == 2.0 == 2.00
etc., por isso deve ser uma string.
Para fornecer um exemplo de por que tem que ser uma string:
Se você formatar 1.toFixed (2), receberá '1.00'.
Não é o mesmo que 1, pois 1 não possui 2 casas decimais.
Sei que o JavaScript não é exatamente uma linguagem de desempenho , mas é provável que você obtenha melhor desempenho para um arredondamento se usar algo como: roundedValue = Math.round (valor * 100) * 0.01
Porque seu uso principal é exibir números? Se você quiser arredondar números, use Math.round()
com fatores apropriados.
'42'
é um número ... o que não é. Só porque uma string contém apenas dígitos não a torna um número. Isto não é PHP. :-P
Aqui está uma versão um pouco mais funcional da resposta m93a
fornecida.
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