Menu

Classe Math em Java: pow, sqrt, abs, round, random e mais

Como usar a classe Math do Java: Math.pow, Math.sqrt, Math.abs, Math.max e Math.min, arredondamento com round, floor e ceil, números aleatórios num intervalo com Math.random, e as constantes PI e E, com o tipo de retorno de cada um.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Uma caixa de ferramentas de métodos estáticos

java.lang.Math é uma classe cheia de funções matemáticas prontas: potências, raízes, valor absoluto, arredondamento, trigonometria, logaritmos e números aleatórios. Duas coisas a tornam fácil de usar:

  • Ela fica em java.lang, que todo arquivo Java importa automaticamente. Não há linha de import para escrever.
  • Todo método é static. Você o chama pelo nome da classe, Math.sqrt(25), e nunca cria um objeto Math. A página de membros estáticos explica o que static significa.

Repare que alguns resultados aparecem com .0 e outros não. Cada método de Math tem um tipo de retorno fixo, e conhecer esse tipo é quase tudo o que há para aprender sobre esta classe.

MétodoO que fazRetorna
Math.pow(a, b)a elevado a bdouble
Math.sqrt(x)raiz quadradadouble
Math.cbrt(x)raiz cúbicadouble
Math.abs(x)valor absolutoo mesmo tipo de x
Math.max(a, b) / Math.min(a, b)o maior / o menor de doiso mais largo dos dois tipos
Math.round(x)inteiro mais próximolong para um double, int para um float
Math.floor(x) / Math.ceil(x)arredonda para baixo / para cimadouble
Math.random()número aleatório de 0,0 até 1,0double
Math.PI, Math.Eas constantes π e edouble

Math.pow: potências

Math.pow(base, exponent) eleva um número a uma potência. Recebe dois parâmetros double e retorna um double, mesmo quando você passa números inteiros:

Para guardar o resultado num int, faça um cast com (int). Para potências inteiras pequenas o resultado double é exato, então o cast dá a resposta certa. É com resultados grandes que o cast dá errado: um double acima de Integer.MAX_VALUE (2.147.483.647) vira exatamente Integer.MAX_VALUE, então (int) Math.pow(2, 40)2147483647. Faça o cast para long em potências maiores, e lembre que acima de 2⁵³ um double não consegue representar todo número inteiro com exatidão. A página de conversão de tipos explica o que um cast faz com o valor.

Java não tem operador de potência. 2 ^ 3 compila, mas ^ é o XOR bit a bit, e o resultado é 1, não 8. Esse é um dos bugs mais comuns de iniciantes em código matemático Java.

Um double de dez milhões ou mais é impresso em notação científica, o que surpreende na primeira vez que você imprime uma potência de dez:

1.0E7 significa 1,0 × 10⁷. O valor é o mesmo; só a forma impressa muda. Faça o cast para long, ou formate com String.format("%.0f", value), para imprimir só os dígitos.

Math.sqrt e Math.cbrt: raízes

Math.sqrt(x) retorna a raiz quadrada de x como double. Math.cbrt(x) retorna a raiz cúbica.

A raiz quadrada de um número negativo não é um número real, então Math.sqrt(-4) retorna NaN ("not a number", não é um número) em vez de lançar uma exceção. NaN se espalha por qualquer conta em que aparece, então verifique as entradas antes de tirar uma raiz se valores negativos forem possíveis. Math.hypot(a, b) calcula sqrt(a*a + b*b) diretamente, um jeito comum de obter a distância entre dois pontos.

Math.abs: valor absoluto

Math.abs(x) remove o sinal. Ao contrário de pow e sqrt, retorna o mesmo tipo que você passa: um int para um int, um double para um double.

O uso típico é uma diferença em que importa o tamanho, não a direção, como a distância entre duas posições.

Math.max e Math.min

Math.max(a, b) retorna o maior de dois valores e Math.min(a, b) o menor. Recebem exatamente dois argumentos. Para três ou mais, aninhe as chamadas:

Quando os dois argumentos têm tipos diferentes, o mais estreito é alargado primeiro. Math.max(3, 7.5) compara dois valores double e retorna um double. O último exemplo limita um valor ao intervalo de 0 a 100: Math.min o limita a 100, e Math.max impede que fique abaixo de 0.

Arredondamento: round, floor, ceil

Java tem três métodos de arredondamento, e eles diferem tanto na direção quanto no tipo de retorno:

  • Math.round vai para o inteiro mais próximo. Um valor exatamente na metade arredonda para cima, na direção do infinito positivo, então 2.5 vira 3 e -2.5 vira -2. Retorna um long para um argumento double (e um int para um float).
  • Math.floor sempre arredonda para baixo, na direção do infinito negativo, e retorna um double.
  • Math.ceil sempre arredonda para cima, na direção do infinito positivo, e retorna um double.
  • Um cast (int) não é arredondamento: ele descarta a parte fracionária, o que leva números positivos para baixo e negativos para cima.

Como Math.round(double) retorna um long, atribuí-lo a um int não compila sem um cast:

int n = Math.round(2.6);          // error: incompatible types: possible lossy conversion from long to int
int m = (int) Math.round(2.6);    // OK, m vale 3
long k = Math.round(2.6);         // OK

Para arredondar para um número de casas decimais, multiplique, arredonde e divida de volta. Dividir por 100.0 (um double) em vez de 100 mantém as casas decimais:

A segunda linha divide um long por um int, o que é divisão inteira, então as casas decimais se perdem. Quando você só precisa mostrar um número arredondado, String.format("%.2f", value) é mais simples e não altera o valor guardado.

Math.random: números aleatórios

Math.random() retorna um double maior ou igual a 0.0 e menor que 1.0. O valor muda a cada chamada, então a saída dos programas desta seção muda toda vez que você aperta Run.

Para obter um número inteiro num intervalo, estique esse valor, faça o cast e desloque. Para um inteiro de min a max, os dois incluídos:

int value = (int) (Math.random() * (max - min + 1)) + min;

Veja como isso funciona para um dado, em que min é 1 e max é 6:

  1. Math.random() * 6 dá um double de 0.0 até 6.0, sem incluir o 6.0.
  2. (int) descarta a fração, dando um de 0, 1, 2, 3, 4, 5.
  3. + 1 desloca isso para 1, 2, 3, 4, 5, 6.

A primeira linha mostra cinco lançamentos aleatórios. A segunda verifica dez mil lançamentos e, na prática, sempre imprime lowest: 1, highest: 6: a fórmula alcança as duas pontas do intervalo e nunca passa delas.

Os parênteses em volta de Math.random() * (max - min + 1) importam. Um cast se aplica ao valor logo depois dele, então (int) Math.random() * 6 converte Math.random() primeiro. Isso é sempre 0, e 0 * 6 é 0, então todo "lançamento" sai igual.

Math.random() serve bem para jogos e exercícios. Para algo além disso, a classe java.util.Random e ThreadLocalRandom.current().nextInt(min, max + 1) (em java.util.concurrent) retornam inteiros diretamente, e Random aceita uma semente (seed) para repetir a mesma sequência em testes. Nenhum deles serve para senhas ou tokens de segurança; para isso, use java.security.SecureRandom.

Math.PI e Math.E

Math.PI (π) e Math.E (o número de Euler, e) são constantes static final double:

Use essas constantes em vez de digitar 3.14. Elas são tão precisas quanto um double permite, e o nome diz a quem lê que número é aquele.

Resultados inteiros contra resultados double

A maioria dos métodos de Math recebe e retorna double. Quando você passa valores int, o Java alarga os argumentos para double automaticamente, mas a conta que você escreve antes da chamada ainda acontece em int. É daí que vem a maioria das respostas erradas:

items / perBox é 7 / 2, e dividir dois valores int descarta o resto, então o resultado é 3 antes mesmo de Math.ceil vê-lo. Math.ceil(3.0) é 3.0. Faça um dos operandos ser double, com um cast ou um literal como 4.0, para a divisão manter a fração. A página de operadores explica a divisão inteira com mais detalhes.

A regra geral: decida qual tipo você quer no final, faça a divisão ou a multiplicação acontecer em double quando as frações importam, e converta de volta para int ou long uma única vez, no final.

Outros métodos úteis

Mais alguns métodos da mesma classe, todos chamados do mesmo jeito:

  • Math.log é o logaritmo natural; Math.log10 é na base 10.
  • Math.floorMod(a, b) dá um resto com o sinal de b, que é o que você quer para dar a volta num intervalo como os dias da semana. O operador % mantém o sinal de a.
  • Os métodos de trigonometria (sin, cos, tan) recebem radianos. Converta graus com Math.toRadians antes.
  • Math.addExact, Math.multiplyExact e seus parentes lançam uma ArithmeticException em caso de overflow, em vez de dar a volta em silêncio para um número negativo.

Perguntas frequentes

Como usar Math.pow em Java?

Math.pow(base, exponent) retorna base elevado a exponent como double, então Math.pow(2, 3) é 8.0. Para guardar o resultado num int, faça um cast: int n = (int) Math.pow(2, 10);1024. Java não tem operador de potência ^; ^ é o XOR bit a bit.

Como gerar um número aleatório num intervalo com Math.random?

Math.random() retorna um double de 0.0 até 1.0, sem incluir o 1.0. Para um número inteiro de min a max, os dois incluídos, use (int) (Math.random() * (max - min + 1)) + min. Um lançamento de dado é (int) (Math.random() * 6) + 1.

Preciso importar a classe Math em Java?

Não. Math fica no pacote java.lang, que todo arquivo Java importa automaticamente. Todos os seus métodos são static, então você os chama pelo nome da classe, como em Math.sqrt(16), sem criar um objeto.

Por que Math.round retorna um long em Java?

Math.round(double) retorna um long porque um double pode guardar valores muito maiores que um int. Atribuir o resultado a um int exige um cast: int n = (int) Math.round(2.6);. Math.round(float) retorna um int.

Qual a diferença entre Math.floor, Math.ceil e Math.round?

Math.floor arredonda para baixo (2.7 vira 2.0, -2.3 vira -3.0), Math.ceil arredonda para cima (2.1 vira 3.0), e Math.round vai para o inteiro mais próximo, com as metades indo para cima (2.5 vira 3). floor e ceil retornam double; round retorna long.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR