JavaScript: arredonda para várias casas decimais, mas retira zeros extras


85

Este é o cenário: estou recebendo .9999999999999999quando deveria 1.0.
Posso perder uma casa decimal de precisão, então estou usando .toFixed(15), o que funciona.

O arredondamento funciona, mas o problema é que me deram 1.000000000000000.
Existe uma maneira de arredondar para um número de casas decimais, mas retirar os espaços em branco extras?

Nota: .toPrecisionnão é o que eu quero; Eu só quero especificar quantos números após a vírgula decimal.
Nota 2: não posso simplesmente usar .toPrecision(1)porque preciso manter a alta precisão para números que realmente têm dados após a vírgula decimal. Idealmente, haveria exatamente tantas casas decimais quantas fossem necessárias (até 15).


O ponto é que .toFixed retorna uma String, portanto, apenas percorrê-la por meio de um Número e, em seguida, de volta para uma String irá reconvertê-la sem os zeros à direita.
Neil

@Nathan: apenas para esclarecimento. Você deseja apenas remover os zeros finais na string obtida com toFixed ()?
Jiri Kriz,

Respostas:


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

4
Não se esqueça de colocá-los entre parênteses ao tratar números negativos: -2.34.toFixed(1)retorna -2.3devido à precedência do operador .
Константин Ван

1
O uso do operador + unário deve ser mais rápido do que a parseFloatfunção: +number.toFixed(13)esta expressão também pode ser usada para remover imprecisões de número do JavaScript, como em 1.0000000000000045.
ygoe


19

Pelo que entendi, você deseja remover os zeros à direita da string obtida por meio de toFixed(). Esta é uma operação de string pura:

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

6
Você é o único que realmente respondeu à pergunta .. obrigado!
Mugen

4
Isso deixa o ponto nos números redondos ("100,00" => "100.")
pckill

5
@pckill se você não quiser que o ponto, você pode incluí-lo na expressão regular para ser substituído ( ...replace(/\.?0+$/, "");).
Zach Snow

Isso falha em 0 e -0 porque 0se torna a string vazia ""e -0se torna -, nenhuma das quais é esperada (em uma estimativa). @ zach-snow sua solução sugerida também falha em 0 e -0.
robocat

@Mugen, qual foi o problema com a resposta do Gus?
trysis

10

Number(n.toFixed(15)) or +(n.toFixed(15)) irá converter a string decimal de 15 casas em um número, removendo os zeros à direita.


1
Pensei em apontar, + (n.toFixed (...)) é muito mais eficiente do que parseFloat. Não sei por que, mas também é mais eficiente do que o número no Chrome.
Domino

8

Se você converter o valor de retorno em um número, os zeros finais serão descartados. Isso também é menos prolixo do que parseFloat()é.

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

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

Este usa o operador + unário , por isso, se usar isso como parte de uma operação de seqüência que você precisa ter uma infix + antes: var n=0.9999999999999999; console.log('output ' + +n.toFixed(2));. Para sua informação, um + unário na frente de uma string o converte em um número. Do MDN: Unary + pode:

converter representações de string de inteiros e flutuantes, bem como os valores não-string true, false e null. Há suporte para números inteiros em formatos decimais e hexadecimais (com prefixo "0x"). Números negativos são suportados (embora não para hexadecimais). Se ele não puder analisar um valor específico, será avaliado como NaN.


@robocat Acabei de fazer uma verificação simples; +(4.1).toFixed(4)está 4.1no Chrome 60 .
Константин Ван

Eu não entendo. Qual foi a razão pela qual esta resposta foi rejeitada?
Константин Ван

@K Você estava certo, então apaguei meu comentário anterior e acrescentei à resposta (acho que estava usando infix + com uma string em lhs, em vez de usar unário + corretamente. Normalmente eu sou mais cuidadoso! Saúde)
robocat

Essa resposta ainda funciona com NaN, Infinity, -Infinity, 3e30 e 0. Algumas outras respostas falham em alguns casos esquivos.
robocat

(4) .toFixed (2) -> "4,00" no Chrome 60.0.3112.113
Daniel Que

1

Nada disso realmente me deu o que eu estava procurando com base no título da pergunta, que era, por exemplo, 5,00 para 5 e 5,10 para 5,1. Minha solução foi a seguinte:

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

Observação: o regex só funciona se places > 0

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


Falha em 5e30(muda o número para 5e3). Casos esquivos são diabólicos!
robocat

0

Existe um método melhor que mantém a precisão e também retira os zeros. Isso leva um número de entrada e, por meio de alguma mágica de projeção, retirará quaisquer zeros à direita. Descobri que 16 é o limite de precisão para mim, o que é muito bom, caso você não coloque um satélite em Plutão.

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

O toFixed()método formata um numberusando a notação de ponto fixo e retorna um string.

Ele aplica uma estratégia de arredondamento pela metade .

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

Como você descreveu, às vezes também resultará em zeros à direita (potencialmente desnecessários).

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

Você pode não querer se livrar desses zeros à direita, basicamente, basta convertê-los de volta para um number. Existem muitas maneiras de fazer isso.

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

Para uma visão geral dos diferentes métodos para converter strings em números, verifique esta pergunta, que tem algumas respostas excelentes.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.