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 deimportpara escrever. - Todo método é
static. Você o chama pelo nome da classe,Math.sqrt(25), e nunca cria um objetoMath. A página de membros estáticos explica o questaticsignifica.
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étodo | O que faz | Retorna |
|---|---|---|
Math.pow(a, b) | a elevado a b | double |
Math.sqrt(x) | raiz quadrada | double |
Math.cbrt(x) | raiz cúbica | double |
Math.abs(x) | valor absoluto | o mesmo tipo de x |
Math.max(a, b) / Math.min(a, b) | o maior / o menor de dois | o mais largo dos dois tipos |
Math.round(x) | inteiro mais próximo | long para um double, int para um float |
Math.floor(x) / Math.ceil(x) | arredonda para baixo / para cima | double |
Math.random() | número aleatório de 0,0 até 1,0 | double |
Math.PI, Math.E | as constantes π e e | double |
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) dá 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.roundvai para o inteiro mais próximo. Um valor exatamente na metade arredonda para cima, na direção do infinito positivo, então2.5vira3e-2.5vira-2. Retorna umlongpara um argumentodouble(e umintpara umfloat).Math.floorsempre arredonda para baixo, na direção do infinito negativo, e retorna umdouble.Math.ceilsempre arredonda para cima, na direção do infinito positivo, e retorna umdouble.- 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:
Math.random() * 6dá umdoublede0.0até6.0, sem incluir o6.0.(int)descarta a fração, dando um de0, 1, 2, 3, 4, 5.+ 1desloca isso para1, 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 deb, que é o que você quer para dar a volta num intervalo como os dias da semana. O operador%mantém o sinal dea.- Os métodos de trigonometria (
sin,cos,tan) recebem radianos. Converta graus comMath.toRadiansantes. Math.addExact,Math.multiplyExacte seus parentes lançam umaArithmeticExceptionem 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); dá 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.