Como arredondar um número para N casas decimais em Java
1. Visão geral
Neste breve artigo, veremos como arredondar um número para casas decimais den em Java.
Leitura adicional:
Número de dígitos em um número inteiro em Java
Aprenda maneiras diferentes de obter o número de dígitos em um número inteiro em Java.
Verifique se um número é primo em Java
Aprenda como verificar a primalidade do número usando Java.
Verifique se uma string é numérica em Java
Explore maneiras diferentes de determinar se uma String é numérica ou não.
2. Números decimais em Java
Java fornece dois tipos primitivos que podem ser usados para armazenar números decimais:floatedouble. Double é o tipo usado por padrão:
double PI = 3.1415;
No entanto, ambos os tiposshould never be used for precise values, como moedas. Para isso, e também para arredondamento, podemos usar a classeBigDecimal.
3. Formatando um Número Decimal
Se quisermos apenas imprimir um número decimal comn dígitos após o ponto decimal, podemos simplesmente formatar a string de saída:
System.out.printf("Value with 3 digits after decimal point %.3f %n", PI);
// OUTPUTS: Value with 3 digits after decimal point 3.142
Como alternativa, podemos formatar o valor com a classeDecimalFormat:
DecimalFormat df = new DecimalFormat("###.###");
System.out.println(df.format(PI));
DecimalFormat nos permite definir explicitamente o comportamento de arredondamento, dando mais controle da saída do queString.format() usado acima.
4. ArredondandoDoubles comBigDecimal
Para arredondardoubles para casas decimais den, podemos escrever umhelper method:
private static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(Double.toString(value));
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
Há uma coisa importante a observar nesta solução - ao construirBigDecimal; devemosalways use BigDecimal(String) constructor. Isso evita problemas com a representação de valores inexatos.
Podemos conseguir o mesmo usando a bibliotecaApache Commons Math:
org.apache.commons
commons-math3
3.5
A versão mais recente pode ser encontradahere.
Depois que a biblioteca é adicionada ao projeto, podemos usar o métodoPrecision.round(), que leva dois argumentos - valor e escala:
Precision.round(PI, 3);
Por padrão, ele usa o mesmo método de arredondamentoHALF_UP que nosso método auxiliar. Portanto, os resultados devem ser os mesmos.
Observe que podemos alterar o comportamento do arredondamento passando o método de arredondamento desejado como um terceiro parâmetro.
5. Arredondamento de duplas comDoubleRounder
DoubleRounder é um utilitário na bibliotecadecimal4j. Ele fornece um método rápido e sem lixo para arredondar dobras de 0 a 18 pontos decimais.
Podemos obter a biblioteca (a versão mais recente pode ser encontradahere) adicionando a dependência aopom.xml:
org.decimal4j
decimal4j
1.0.3
Agora, podemos simplesmente usar:
DoubleRounder.round(PI, 3);
No entanto,DoubleRounder falha em alguns cenários, por exemplo:
System.out.println(DoubleRounder.round(256.025d, 2));
// OUTPUTS: 256.02 instead of expected 256.03
6. Math.Round() Method
Outra maneira de arredondar números é usar o método Math.Round ().
Neste caso, podemos controlar o número den de casas decimais multiplicando e dividindo por10^n:
public static double roundAvoid(double value, int places) {
double scale = Math.pow(10, places);
return Math.round(value * scale) / scale;
}
This method is not recommended as it’s truncating the value. Em muitos casos, os valores são arredondados incorretamente:
System.out.println(roundAvoid(1000.0d, 17));
// OUTPUTS: 92.23372036854776 !!
System.out.println(roundAvoid(260.775d, 2));
// OUTPUTS: 260.77 instead of expected 260.78
E assim, este método é listado aqui apenas para fins de aprendizado.
7. Conclusão
Neste tutorial rápido, cobrimos diferentes técnicas para arredondar números para casas decimais den.
Podemos simplesmente formatar a saída sem alterar o valor, ou podemos arredondar a variável usando um método auxiliar. Também cobrimos algumas bibliotecas que lidam com esse problema.
O código usado durante a discussão pode ser encontradoover on GitHub.