Em JavaScript, ao converter de um float para uma string, como posso obter apenas 2 dígitos após o ponto decimal? Por exemplo, 0,34 em vez de 0,3445434.
Em JavaScript, ao converter de um float para uma string, como posso obter apenas 2 dígitos após o ponto decimal? Por exemplo, 0,34 em vez de 0,3445434.
Respostas:
var result = Math.round(original*100)/100;
Os detalhes , caso o código não seja auto-explicativo.
edit: ... ou apenas use toFixed
, como proposto por Tim Büthe . Esqueci esse, obrigado (e um voto positivo) pelo lembrete :)
toFixed()
vai imitar o que algo como printf()
faz em C. No entanto, toFixed()
e Math.round()
irá lidar com arredondamento diferente. Nesse caso, toFixed()
terá o mesmo tipo de efeito Math.floor()
que teria (desde que você multiplique o original por 10 ^ n antes e ligue toFixed()
com n dígitos). A "correção" da resposta depende muito do que o OP deseja aqui, e ambas são "corretas" à sua maneira.
Existem funções para arredondar números. Por exemplo:
var x = 5.0364342423;
print(x.toFixed(2));
imprimirá 5.04.
EDIT: Fiddle
var x = 5.036432346; var y = x.toFixed(2) + 100;
y
será igual"5.03100"
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
…
Tenha cuidado ao usar toFixed()
:
Primeiro, o arredondamento do número é feito usando a representação binária do número, o que pode levar a um comportamento inesperado. Por exemplo
(0.595).toFixed(2) === '0.59'
em vez de '0.6'
.
Segundo, há um bug do IE toFixed()
. No IE (pelo menos até a versão 7, não verificou o IE8), o seguinte é verdadeiro:
(0.9).toFixed(0) === '0'
Pode ser uma boa ideia seguir a sugestão de kkyy ou usar uma toFixed()
função personalizada , por exemplo
function toFixed(value, precision) {
var power = Math.pow(10, precision || 0);
return String(Math.round(value * power) / power);
}
.toFixed()
método nativo no valor de retorno, que adicionará a quantidade necessária de precisão, por exemplo:: return (Math.round(value * power) / power).toFixed(precision);
e também retornará o valor como uma string. Caso contrário, precisão de 20 é ignorado para decimais menores
toFixed
: observe que aumentar a precisão pode gerar resultados inesperados:, (1.2).toFixed(16) === "1.2000000000000000"
enquanto (1.2).toFixed(17) === "1.19999999999999996"
(no Firefox / Chrome; no IE8, o último não é válido devido à menor precisão que o IE8 pode oferecer internamente).
(0.598).toFixed(2)
não produz 0.6
. Produz 0.60
:)
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
.
Outro problema a ter em atenção é que toFixed()
pode produzir zeros desnecessários no final do número. Por exemplo:
var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"
A idéia é limpar a saída usando um RegExp
:
function humanize(x){
return x.toFixed(6).replace(/\.?0*$/,'');
}
O RegExp
coincide com os zeros à direita (e, opcionalmente, o ponto decimal) para ter certeza que parece ser bom para inteiros também.
humanize(23-7.37)
"15.63"
humanize(1200)
"1200"
humanize(1200.03)
"1200.03"
humanize(3/4)
"0.75"
humanize(4/3)
"1.333333"
var x = 0.3445434
x = Math.round (x*100) / 100 // this will make nice rounding
Há um problema com todas essas soluções flutuando usando multiplicadores. Infelizmente, as soluções de kkyy e Christoph estão erradas.
Teste o seu código para o número 551.175 com 2 casas decimais - ele será arredondado para 551,17 enquanto deve ser 551,18 ! Mas se você testar para ex. 451.175, tudo bem - 451.18. Portanto, é difícil identificar esse erro à primeira vista.
O problema está na multiplicação: tente 551.175 * 100 = 55117.49999999999 (ups!)
Então, minha ideia é tratá-lo com toFixed () antes de usar Math.round ();
function roundFix(number, precision)
{
var multi = Math.pow(10, precision);
return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}
toFixed
é afetado - (0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
... Qualquer que seja o método usado, adicione um épsilon antes do arredondamento.
A chave aqui eu acho que é arredondar corretamente primeiro, então você pode convertê-lo em String.
function roundOf(n, p) {
const n1 = n * Math.pow(10, p + 1);
const n2 = Math.floor(n1 / 10);
if (n1 >= (n2 * 10 + 5)) {
return (n2 + 1) / Math.pow(10, p);
}
return n2 / Math.pow(10, p);
}
// All edge cases listed in this thread
roundOf(95.345, 2); // 95.35
roundOf(95.344, 2); // 95.34
roundOf(5.0364342423, 2); // 5.04
roundOf(0.595, 2); // 0.60
roundOf(0.335, 2); // 0.34
roundOf(0.345, 2); // 0.35
roundOf(551.175, 2); // 551.18
roundOf(0.3445434, 2); // 0.34
Agora você pode formatar esse valor com segurança com toFixed (p). Então, com o seu caso específico:
roundOf(0.3445434, 2).toFixed(2); // 0.34
Se você quiser a string sem arredondar, poderá usar este RegEx (talvez não seja a maneira mais eficiente ... mas é realmente fácil)
(2.34567778).toString().match(/\d+\.\d{2}/)[0]
// '2.34'
function trimNumber(num, len) {
const modulu_one = 1;
const start_numbers_float=2;
var int_part = Math.trunc(num);
var float_part = String(num % modulu_one);
float_part = float_part.slice(start_numbers_float, start_numbers_float+len);
return int_part+'.'+float_part;
}
return float_part ? int_part+'.'+float_part : int_part;
caso contrário, se você passou Integer, ele retornou número com um ponto no final (exemplo de entrada: 2100
, saída: 2100.
)
Talvez você também queira separador decimal? Aqui está uma função que acabei de criar:
function formatFloat(num,casasDec,sepDecimal,sepMilhar) {
if (num < 0)
{
num = -num;
sinal = -1;
} else
sinal = 1;
var resposta = "";
var part = "";
if (num != Math.floor(num)) // decimal values present
{
part = Math.round((num-Math.floor(num))*Math.pow(10,casasDec)).toString(); // transforms decimal part into integer (rounded)
while (part.length < casasDec)
part = '0'+part;
if (casasDec > 0)
{
resposta = sepDecimal+part;
num = Math.floor(num);
} else
num = Math.round(num);
} // end of decimal part
while (num > 0) // integer part
{
part = (num - Math.floor(num/1000)*1000).toString(); // part = three less significant digits
num = Math.floor(num/1000);
if (num > 0)
while (part.length < 3) // 123.023.123 if sepMilhar = '.'
part = '0'+part; // 023
resposta = part+resposta;
if (num > 0)
resposta = sepMilhar+resposta;
}
if (sinal < 0)
resposta = '-'+resposta;
return resposta;
}
Não há como evitar arredondamentos inconsistentes para preços com x.xx5 como valor real usando multiplicação ou divisão. Se você precisar calcular preços corretos no lado do cliente, mantenha todos os valores em centavos. Isso se deve à natureza da representação interna dos valores numéricos em JavaScript. Observe que o Excel sofre dos mesmos problemas para que a maioria das pessoas não notasse os pequenos erros causados por esse fenômeno. No entanto, os erros podem se acumular sempre que você acrescenta muitos valores calculados. Existe uma teoria completa envolvendo a ordem dos cálculos e outros métodos para minimizar o erro no resultado final. Para enfatizar os problemas com valores decimais, observe que 0,1 + 0,2 não é exatamente igual a 0,3 no JavaScript, enquanto 1 + 2 é igual a 3.
/** don't spend 5 minutes, use my code **/
function prettyFloat(x,nbDec) {
if (!nbDec) nbDec = 100;
var a = Math.abs(x);
var e = Math.floor(a);
var d = Math.round((a-e)*nbDec); if (d == nbDec) { d=0; e++; }
var signStr = (x<0) ? "-" : " ";
var decStr = d.toString(); var tmp = 10; while(tmp<nbDec && d*tmp < nbDec) {decStr = "0"+decStr; tmp*=10;}
var eStr = e.toString();
return signStr+eStr+"."+decStr;
}
prettyFloat(0); // "0.00"
prettyFloat(-1); // "-1.00"
prettyFloat(-0.999); // "-1.00"
prettyFloat(0.5); // "0.50"
Eu uso esse código para formatar carros alegóricos. É baseado, toPrecision()
mas remove zeros desnecessários. Gostaria de receber sugestões de como simplificar a regex.
function round(x, n) {
var exp = Math.pow(10, n);
return Math.floor(x*exp + 0.5)/exp;
}
Exemplo de uso:
function test(x, n, d) {
var rounded = rnd(x, d);
var result = rounded.toPrecision(n);
result = result.replace(/\.?0*$/, '');
result = result.replace(/\.?0*e/, 'e');
result = result.replace('e+', 'e');
return result;
}
document.write(test(1.2000e45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2000e+45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2340e45, 3, 2) + '=' + '1.23e45' + '<br>');
document.write(test(1.2350e45, 3, 2) + '=' + '1.24e45' + '<br>');
document.write(test(1.0000, 3, 2) + '=' + '1' + '<br>');
document.write(test(1.0100, 3, 2) + '=' + '1.01' + '<br>');
document.write(test(1.2340, 4, 2) + '=' + '1.23' + '<br>');
document.write(test(1.2350, 4, 2) + '=' + '1.24' + '<br>');