Porque é complicado
O objecto Matemático do JavaScript fornece um método de arredondamento para números inteiros. Se quisermos arredondar para um determinado número de casas decimais, então temos de ser nós a tratar disso. Este post não entra nos detalhes da aritmética da vírgula flutuante, mas a falta dela é que a maioria das linguagens de programação utilizam uma representação binária da vírgula flutuante que só pode aproximar muitas fracções decimais. Isto resulta em erros de arredondamento para as abordagens mais comuns de arredondamento em JavaScript.
Erros de arredondamento
As soluções mais comuns para arredondamento a uma casa decimal é usar Number.prototype.toFixed()
, ou multiplicar a vírgula flutuante por alguma potência de 10 para alavancar Math.round()
. Ambos os trabalhos, excepto por vezes um decimal de 5 é arredondado para baixo em vez de para cima.
Number((1.005).toFixed(2)); // 1 instead of 1.01
Math.round(1.005*100)/100; // 1 instead of 1.01
Uma melhor solução
O problema do arredondamento pode ser evitado através da utilização de números representados em notação exponencial:
Number(Math.round(1.005+'e2')+'e-2'); // 1.01
E para abstrair isso em algo mais utilizável:
function round(value, decimals) { return Number(Math.round(value+'e'+decimals)+'e-'+decimals);}round(1.005, 2); // 1.01