Páginas

terça-feira, 7 de junho de 2011

Arredondando Números em Java

A classe java.lang.Math disponibiliza alguns métodos para que possamos recuperar valores inteiros arredondados de números com ponto flutuante (float e double). Os métodos disponíveis variam em sua forma de obter os resultados, vamos tentar clarear um pouco o que acontece em cada um deles.
Obs. Se quiser arredondamentos para as casas decimais veja esta outra postagem dedicada ao assunto.

Math.floor()

Recebe um double e retorna um double.

Este método retorna o maior valor possível que seja menor ou igual ao argumento passado e seja matematicamente igual a um inteiro.

Exemplos:
para -1,6 teremos -2,0
para -1,5 teremos -2,0
para -1,4 teremos -2,0
para 1,4 teremos 1,0
para 1,5 teremos 1,0
para 1,6 teremos 1,0
Este método não possui segredos, em linguagem comum podemos dizer que este método sempre arredonda "para baixo".

Math.rint()

Recebe um double e retorna um double.

Este método retorna o valor, matematicamente igual a um inteiro, que seja mais próximo ao argumento passado. Caso o argumento passado possua dois valores inteiros igualmente distantes, será retornado o valor par.

Exemplos:
para -1,6 teremos -2,0
para -1,5 teremos -2,0
para -1,4 teremos -1,0
para 1,4 teremos 1,0
para 1,5 teremos 2,0
para 1,6 teremos 2,0
Neste método o segredo está nas metades, onde o arredondamento será para o valor par, nas outras situações o arredondamento obedece a regra geral da matemática.

Math.round()

Recebe um double ou um float e retorna um long ou um int, respectivamente.

Talvez possamos dizer que este método é o arredondamento padrão. Assim como no método rint este método retorna o valor, matematicamente igual a um inteiro, que seja mais próximo ao argumento passado. A diferença está quando existem dois valores inteiros igualmente distantes, já que este método irá retornar, sempre, o valor maior.

Exemplos:
para -1,6 teremos -2
para -1,5 teremos -1
para -1,4 teremos -1
para 1,4 teremos 1
para 1,5 teremos 2
para 1,6 teremos 2
Neste método o segredo está nas metades, onde o arredondamento será "para cima", nas outras situações o arredondamento obedece a regra geral da matemática.

Não existe um método diretamente contrário a este, ou seja, que retorne um arredondamento "para baixo" nas metades, mas isto pode ser obtido através da inversão de sinais no retorno e no argumento: -Math.round(-argumento).

Math.ceil()

Recebe um double e retorna um double.

Este método é o inverso do método floor, sendo que para este método o retorno será o menor valor possível que seja maior ou igual ao argumento passado e seja matematicamente igual a um inteiro.

Exemplos:
para -1,6 teremos -1,0
para -1,5 teremos -1,0
para -1,4 teremos -1,0
para 1,4 teremos 2,0
para 1,5 teremos 2,0
para 1,6 teremos 2,0
Este método não possui segredos, em linguagem comum podemos dizer que este método sempre arredonda "para cima".

Exemplos na prática

Como de costume, vamos ao código de exemplo para colocarmos a mão na massa e neste caso visualizarmos as diferenças entre cada método, então...
public class Arredondamentos {

 public static void main(String[] args) {
  System.out.println("|   Valor    |   floor    |    rint    |   round    | -round(-d) |    ceil    |");
  for(int i = -45; i <= 45; i += 10) {
   for(int j = -1; j <= 1; j++) {
    double d = (i + j) / 10.0;
    System.out.println(String.format("| %10f | %10f | %10f | %10d | %10d | %10f |", d, Math.floor(d), Math.rint(d), Math.round(d), -Math.round(-d), Math.ceil(d)));
   }
  }
 }
}
Neste pequeno código pulei alguns valores para se ater aos valores que podem definir mudanças nos retornos dos métodos, mas você pode mudar o código para obter todos os resultados que desejar.

Outro ponto de análise é o uso de inteiros e divisões por 10, isto foi feito para obter valores de ponto flutuante mais próximos ao esperado, já que o uso de double na estrutura de laço pode gerar valores um pouco fora do esperado.

Arredondando as casas decimais

Lembrando que este post trata de arredondamentos com resultados inteiros, para arredondar as casas decimais, como em cálculos monetários por exemplo, não deixe de verificar o nosso post dedicado a este assunto:
http://claudioweiler.blogspot.com.br/2011/06/arredondamento-de-casas-decimais-em.html

2 comentários:

  1. Valeu Cláudio! Bom post e muito útil. Pesquisei em outros lugares e as explicações muitas vezes eram dúbias.
    Parabéns!

    ResponderExcluir

Olá! Antes de postar seu comentário, por favor, observe que comentários técnicos, elogios e sugestões são antecipadamente agradecidos, esclarecimentos sobre os conceitos envolvidos na postagem serão respondidos da melhor forma possível, mas pedidos de ajuda técnica ou suporte individual deverão ser feitos através do formulário de contato. Grato!