Java Operadores Aritméticos
Programas fazem contas o tempo todo: o total de uma compra, a média da turma, quantas caixas cabem num caminhão. Os operadores aritméticos são os símbolos dessas contas. Quatro deles você conhece da escola; os outros (%, ++ e --) são novidade e muito usados. Nesta aula você vai ver cada um, com atenção especial à divisão, que tem as maiores surpresas.
- Os operadores
+,-,*,/e%. - A diferença entre divisão inteira e decimal.
- Para que serve o resto da divisão (
%), inclusive com negativos. - O incremento e o decremento (
++e--), nas formas "pré" e "pós". - O que acontece ao dividir por zero.
Os cinco operadores
Um operador é um símbolo que faz uma operação com valores; os valores são os operandos. Em 17 + 5, o operador é + e os operandos são 17 e 5. A Ana tem 17 maçãs para dividir entre 5 pessoas:
public class Main {
public static void main(String[] args) {
int macas = 17;
int pessoas = 5;
System.out.println(macas + pessoas);
System.out.println(macas - pessoas);
System.out.println(macas * pessoas);
System.out.println(macas / pessoas);
System.out.println(macas % pessoas);
}
}
$ javac Main.java && java Main 22 12 85 3 « 17 / 5: cada pessoa recebe 3 maçãs inteiras 2 « 17 % 5: sobram 2 maçãs
| Operador | Nome | Exemplo | Resultado |
|---|---|---|---|
+ | Soma (adição) | 17 + 5 | 22 |
- | Subtração | 17 - 5 | 12 |
* | Multiplicação (asterisco, não x) | 17 * 5 | 85 |
/ | Divisão (barra, não ÷) | 17 / 5 | 3 (inteiros!) |
% | Resto da divisão (módulo) | 17 % 5 | 2 |
Com String, o + tem outro papel: colar textos (Concatenação). Os outros operadores aritméticos não funcionam com texto. E não existe operador de potência: 2 ^ 3 compila, mas é outra coisa (dá 1); para 2³, use Math.pow(2, 3), que dá 8.0 (Math).
Brinque com o código: mude a quantidade de maçãs e de pessoas. Tente valores em que a divisão é exata (20 e 5) e valores em que sobra muito (19 e 5).
public class Main {
public static void main(String[] args) {
int macas = 17;
int pessoas = 5;
System.out.println("Cada pessoa recebe: " + macas / pessoas);
System.out.println("Sobram: " + macas % pessoas);
}
}
Divisão inteira × divisão decimal
A regra mais importante desta aula: quando os dois operandos são inteiros, a divisão é inteira. O resultado é um inteiro e a parte decimal é jogada fora (não é arredondada). Basta um dos dois ser decimal para a divisão ser decimal:
public class Main {
public static void main(String[] args) {
System.out.println(7 / 2);
System.out.println(7.0 / 2);
System.out.println(7 / 2.0);
System.out.println(7.0 / 2.0);
System.out.println(1 / 3);
System.out.println(2 / 3);
System.out.println(-7 / 2);
int soma = 15;
int n = 2;
System.out.println(soma / n);
System.out.println((double) soma / n);
System.out.println(soma / (double) n);
System.out.println((double) (soma / n));
System.out.println(soma * 1.0 / n);
}
}
$ javac Main.java && java Main 3 « 7 / 2: inteiros, o .5 some 3.5 3.5 3.5 0 « 1 / 3 = 0,333... → 0 0 « 2 / 3 = 0,666... → 0 (cortou, não arredondou para 1) -3 « corta em direção ao zero: -3,5 → -3 7 « soma / n com duas variáveis int 7.5 « (double) soma / n 7.5 « soma / (double) n 7.0 « (double) (soma / n): tarde demais, a divisão já foi inteira 7.5 « soma * 1.0 / n: o truque de multiplicar por 1.0
Por que o Java faz assim? Porque é o que a divisão inteira significa: "quantas vezes o 2 cabe inteiro no 7?" Três vezes. Isso é útil (distribuir maçãs, calcular páginas, converter segundos em minutos), mas é a causa número um de médias erradas.
Para fazer uma divisão decimal com variáveis int | Resultado |
|---|---|
(double) soma / n | Recomendado: o casting converte soma antes de dividir. |
soma / (double) n | Também funciona. |
soma * 1.0 / n | Funciona; é um truque comum, mas menos claro. |
(double) (soma / n) | Errado: divide primeiro (inteiro) e converte depois. |
Os detalhes do casting e da "promoção" de tipos estão em Conversão de Tipos.
O resto da divisão: %
O % não tem nada a ver com porcentagem: ele dá o resto da divisão inteira, aquele número que sobrava na "conta de dividir" da escola. Em inglês o nome é modulo, e por isso muita gente o chama de "módulo".
public class Main {
public static void main(String[] args) {
System.out.println(10 % 3);
System.out.println(9 % 3);
System.out.println(2 % 5);
System.out.println(-7 % 3);
System.out.println(7 % -3);
System.out.println(-7 % -3);
System.out.println(Math.floorMod(-7, 3));
System.out.println(7.5 % 2);
System.out.println(14 % 2);
System.out.println(15 % 2);
int segundos = 125;
System.out.println(segundos / 60 + " min e " + segundos % 60 + " s");
int numero = 4827;
System.out.println(numero % 10);
}
}
$ javac Main.java && java Main 1 « 10 = 3 × 3 + 1 0 « 9 é divisível por 3: resto zero 2 « 2 = 5 × 0 + 2 (o menor dividido pelo maior sobra inteiro) -1 « o sinal do resto é o sinal do PRIMEIRO número 1 -1 2 « Math.floorMod: resto sempre com o sinal do divisor 1.5 « também funciona com double 0 « 14 é par 1 « 15 é ímpar 2 min e 5 s 7 « o último dígito
Para que serve o resto
| Uso | Como | Exemplo |
|---|---|---|
| Saber se é par ou ímpar | n % 2 dá 0 (par) ou não (ímpar) | 14 % 2 → 0 |
| Saber se é divisível | n % d == 0 | 9 % 3 → 0 |
| Converter unidades | / para a parte inteira, % para o que sobra | 125 s → 2 min e 5 s |
| Pegar o último dígito | n % 10 | 4827 % 10 → 7 |
| Dar a volta num ciclo (dias da semana, relógio) | (hora + 5) % 24 | 22h + 5h → 3 |
Resto com números negativos
Em Java, o resultado de % tem sempre o sinal do primeiro operando: -7 % 3 dá -1, não 2. Isso vem da divisão inteira, que corta em direção ao zero (-7 / 3 = -2, e -2 × 3 + (-1) = -7). Se você precisa de um resto sempre positivo (por exemplo, para "voltar" dias da semana), use Math.floorMod(-7, 3), que dá 2.
n % 2 == 1 falha para ímpares negativos, porque -3 % 2 dá -1. O teste seguro é n % 2 != 0 ("o resto não é zero"). O == e o != estão em Operadores de Comparação.
Missão: a música tem 200 segundos. Complete a linha para mostrar 3 min e 20 s, usando / para os minutos e % para os segundos que sobram.
public class Main {
public static void main(String[] args) {
int duracao = 200;
int minutos = 0;
int segundos = 0;
System.out.println(minutos + " min e " + segundos + " s");
}
}
public class Main {
public static void main(String[] args) {
int duracao = 200;
int minutos = duracao / 60;
int segundos = duracao % 60;
System.out.println(minutos + " min e " + segundos + " s");
}
}
Incremento e decremento: ++ e --
Somar 1 ou subtrair 1 de uma variável é tão comum (contar alunos, avançar uma senha na fila, contar voltas de um for) que o Java tem operadores só para isso:
| Operador | Nome | Equivale a |
|---|---|---|
a++ ou ++a | Incremento ("aumentar") | a = a + 1 |
a-- ou --a | Decremento ("diminuir") | a = a - 1 |
Numa linha sozinha, a++; e ++a; fazem exatamente a mesma coisa. A diferença só aparece quando o operador é usado dentro de outra expressão (numa atribuição, num println):
- Pós-incremento
x++(o++depois): usa o valor atual e depois soma 1. - Pré-incremento
++x(o++antes): primeiro soma 1 e depois usa o valor novo.
public class Main {
public static void main(String[] args) {
int a = 5;
a++;
System.out.println(a);
a--;
System.out.println(a);
++a;
System.out.println(a);
int x = 5;
int y = x++;
System.out.println("x = " + x + ", y = " + y);
int p = 5;
int q = ++p;
System.out.println("p = " + p + ", q = " + q);
int c = 10;
System.out.println(c++);
System.out.println(c);
System.out.println(++c);
System.out.println(c--);
System.out.println(c);
}
}
$ javac Main.java && java Main 6 « a++ sozinho: 5 → 6 5 « a--: 6 → 5 6 « ++a sozinho: igual ao a++ x = 6, y = 5 « y = x++: y recebeu o valor ANTIGO (5), depois x virou 6 p = 6, q = 6 « q = ++p: p virou 6 ANTES, e q recebeu 6 10 « println(c++): mostra 10, depois c vira 11 11 12 « println(++c): c vira 12, depois mostra 12 « println(c--): mostra 12, depois c vira 11 11
Uma forma de lembrar: leia da esquerda para a direita. Em x++, você "vê" o x primeiro (usa o valor) e o ++ depois (soma). Em ++x, o ++ vem primeiro.
++ sozinho na linha
Misturar ++ com outras contas (y = x++ + ++x) é um ótimo exercício de prova e um péssimo código: ninguém entende de primeira. No dia a dia, escreva contador++; numa linha própria e use o valor na linha seguinte. A armadilha mais famosa: x = x++; não muda x (o x recebe o valor antigo de volta); um programa com int x = 5; x = x++; mostra 5.
Missão: na fila do banco, a primeira senha chamada deve ser a 1. Mas o programa mostra Próxima senha: 0, porque usa o pós-incremento. Troque para o pré-incremento para que ele mostre Próxima senha: 1.
public class Main {
public static void main(String[] args) {
int fila = 0;
System.out.println("Próxima senha: " + fila++);
}
}
public class Main {
public static void main(String[] args) {
int fila = 0;
System.out.println("Próxima senha: " + ++fila);
}
}
Sinal: -x e +x
O - também funciona com um único operando, para trocar o sinal: se temperatura vale 5, -temperatura vale -5. O + unário existe, mas não faz nada. Esses operadores de um operando só se chamam unários (o ++ e o -- também são). 3 - -2 dá 5: menos com menos.
Divisão por zero
O que acontece se a Ana dividir 10 bolos entre 0 convidados? Depende do tipo:
public class Main {
public static void main(String[] args) {
int bolos = 10;
int convidados = 0;
System.out.println(10.0 / 0);
System.out.println(bolos / convidados);
}
}
$ javac Main.java && java Main Infinity Exception in thread "main" java.lang.ArithmeticException: / by zero at Main.main(Main.java:6)
| Conta | O que acontece |
|---|---|
Inteiro / 0 ou inteiro % 0 | O programa para com ArithmeticException: / by zero ("exceção aritmética: divisão por zero"), apontando a linha (Main.java:6). |
double / 0 | Não para: o resultado é Infinity, -Infinity ou NaN (0.0 / 0). Veja double e float. |
Repare que o programa compilou: o javac não tem como saber que convidados vai valer zero. Mesmo System.out.println(10 / 0);, com o zero escrito no código, compila e só falha ao rodar. Divisões cujo divisor pode ser zero devem ser protegidas com um if (if (convidados != 0)) ou tratadas com try e catch.
Quando dá errado
$ javac Main.java && java Main Exception in thread "main" java.lang.ArithmeticException: / by zero at Main.main(Main.java:3)
O que quer dizer: uma divisão (ou resto) de inteiros teve divisor zero na linha indicada. A mesma mensagem aparece para %: 10 % 0 também diz / by zero.
Como consertar: descubra por que o divisor chegou a zero (uma lista vazia? um valor que o usuário digitou?) e confira antes de dividir.
O que aconteceu: divisão inteira. soma / quantidade com duas variáveis int descarta a parte decimal, mesmo guardando num double.
Como consertar: (double) soma / quantidade.
++ num valor: "unexpected type … required: variable, found: value"
$ javac Main.java
Main.java:5: error: unexpected type
5++;
^
required: variable
found: value
1 error
O que quer dizer: "tipo inesperado: era preciso uma variável, foi encontrado um valor". O ++ guarda o resultado de volta, então só funciona em variáveis; não dá para "incrementar o 5". O mesmo vale para (a + b)++.
Como consertar: use ++ só em variáveis. Para obter o valor seguinte sem guardar, escreva 5 + 1.
$ javac Main.java
Main.java:4: error: bad operand types for binary operator '-'
String b = a - "a";
^
first type: String
second type: String
1 error
O que quer dizer: "tipos de operando inválidos para o operador binário '-'". Com String, só o + funciona (para colar). first type e second type dizem os tipos dos dois lados.
Como consertar: se os textos guardam números, converta antes com Integer.parseInt (Conversão de Tipos). Para manipular texto, use os Métodos de String.
"Total: " + 3 + 2 mostrou Total: 32
O que aconteceu: depois de um texto, o + cola em vez de somar: primeiro "Total: " + 3 vira "Total: 3", depois cola o 2.
Como consertar: parênteses em volta da conta: "Total: " + (3 + 2) mostra Total: 5. Veja Precedência.
Referência
| Operador | Faz | Exemplo → resultado | Cuidado |
|---|---|---|---|
+ | Soma (ou cola texto) | 7 + 2 → 9 | Com String, cola |
- | Subtração / troca de sinal | 7 - 2 → 5; -x | |
* | Multiplicação | 7 * 2 → 14 | Overflow com números grandes |
/ | Divisão | 7 / 2 → 3; 7.0 / 2 → 3.5 | Inteiros: corta; / 0: exceção |
% | Resto | 7 % 2 → 1 | Sinal do primeiro operando |
x++ | Usa, depois soma 1 | y = x++ | Só em variáveis |
++x | Soma 1, depois usa | y = ++x | Só em variáveis |
x-- / --x | O mesmo, subtraindo 1 | vidas-- | |
Math.pow(a, b) | Potência (não é operador) | Math.pow(2, 3) → 8.0 | 2 ^ 3 não é potência |
Math.floorMod(a, b) | Resto com o sinal do divisor | Math.floorMod(-7, 3) → 2 |
Atalhos como total += preco estão em Operadores de Atribuição; a ordem em que as contas são feitas (2 + 3 * 4) está em Precedência.
Exercícios
1. Divisão inteira
Quanto vale 19 / 4 em Java?
2. O resto
Quanto vale 19 % 4?
3. Par ou ímpar
Complete a expressão que dá 0 quando n é par:
4. Média decimal
Complete o casting para a média de soma e n (ambos int) ter casas decimais:
5. Depois de int x = 3; int y = x++;, quanto valem x e y?
6. O que acontece ao executar int r = 10 / 0;?
7. Quanto vale -7 % 3 em Java?
Resumo
+ - * /são as quatro operações;%é o resto da divisão inteira.- Dois inteiros dão divisão inteira:
7 / 2=3, cortando a parte decimal. Para decimais, um dos lados deve serdouble:(double) soma / n. %serve para par/ímpar, divisibilidade, converter unidades e pegar o último dígito. O sinal do resto é o do primeiro número;Math.floorModdá resto positivo.x++usa e depois soma;++xsoma e depois usa. Sozinhos na linha, são iguais.- Inteiro dividido por zero:
ArithmeticException: / by zero.doubledividido por zero:InfinityouNaN.