W3docs

Números em Java

Trabalhe com tipos numéricos em Java — int, long, float, double — e entenda precisão, overflow e a classe Number.

Java distingue números inteiros e de ponto flutuante, e dentro de cada família há vários tamanhos. Escolher o tipo correto é importante tanto para a correção (precisão, intervalo) quanto para o desempenho. Este capítulo é um guia focado nos tipos numéricos, seus literais, conversões e as armadilhas que pegam iniciantes de surpresa. Ele assume que você já sabe como declarar uma variável e já viu o conjunto completo de tipos de dados primitivos.

Os primitivos numéricos

TipoBitsIntervaloEstilo de literal padrão
byte8-128 a 127byte b = 10;
short16-32.768 a 32.767short s = 30_000;
int32-2³¹ a 2³¹-1 (≈ ±2,1 bilhões)int i = 1_000_000;
long64-2⁶³ a 2⁶³-1long l = 9_000L;
float32IEEE 754 precisão simples (~7 dígitos)float f = 3.14f;
double64IEEE 754 precisão dupla (~16 dígitos)double d = 3.14;

No dia a dia com Java:

  • Use int para contadores, índices e a maioria dos valores inteiros.
  • Use long quando você pode ultrapassar ~2 bilhões (tamanhos de arquivo, milissegundos desde a época, geradores de ID).
  • Use double para cálculos de ponto flutuante.
  • Use float apenas quando a memória é limitada ou uma API exige.

Literais inteiros

Dígitos simples são int:

int answer = 42;
int million = 1_000_000;     // underscores are ignored

Sufixo L (maiúsculo preferido) para long:

long big = 9_000_000_000L;

Prefixo 0x para hex, 0b para binário, 0 para octal:

int hex = 0xFF;        // 255
int bin = 0b1010;      // 10
int oct = 0755;        // 493 — be careful, easy to write by accident

(Literais octais são uma fonte frequente de bugs — 0123 não é 123, é 83. Evite zeros à esquerda a menos que realmente queira octal.)

Literais de ponto flutuante

Decimais simples são double:

double pi = 3.14159;
double e = 2.71828;

Sufixo f para float, d para double explícito (opcional):

float pif = 3.14f;
double pid = 3.14d;

Notação científica funciona:

double avogadro = 6.022e23;
double tiny = 1.0e-9;

Convertendo entre tipos numéricos

Java realiza uma conversão de alargamento automaticamente quando um tipo menor flui para um maior (nenhum dado pode ser perdido):

int x = 7;
double promoted = x;   // 7.0 — int widens to double automatically

O caminho inverso é o estreitamento: o valor pode não caber, então Java força você a escrever um cast explícito e descarta silenciosamente o que não couber. Truncamento, não arredondamento:

double d = 9.99;
int i = (int) d;       // 9 — the fraction is dropped, never rounded

long big = 9_000_000_000L;
int truncated = (int) big;   // 410065408 — high bits lost, value is garbage

Por causa disso, só estreite quando tiver certeza de que o valor cabe. Para arredondar um double para o inteiro mais próximo em vez de truncar, use Math.round (veja Java Math).

Conversões também acontecem dentro de expressões. A divisão inteira descarta o resto, o que surpreende iniciantes:

System.out.println(7 / 2);     // 3   — both operands are int, so int division
System.out.println(7 / 2.0);   // 3.5 — one double operand promotes the whole expression

Para as regras completas sobre casts explícitos, veja Java Type Casting.

Overflow

A aritmética inteira envolve silenciosamente os limites do tipo. Nenhuma exceção é lançada:

int max = Integer.MAX_VALUE;
System.out.println(max + 1);   // -2147483648 (Integer.MIN_VALUE)

Para aritmética com verificação de overflow, use a família Math.exact:

Math.addExact(Integer.MAX_VALUE, 1);   // throws ArithmeticException
Math.multiplyExact(100_000, 100_000);  // throws too

Útil quando a correção importa mais que o desempenho — cálculos financeiros, tamanhos de alocação, etc.

Precisão de ponto flutuante

double e float são IEEE 754 binário — eles não conseguem representar a maioria das frações decimais com exatidão:

System.out.println(0.1 + 0.2);   // 0.30000000000000004

Nunca compare valores de ponto flutuante com ==. Compare dentro de uma tolerância:

double diff = Math.abs(a - b);
if (diff < 1e-9) { /* close enough */ }

Para quantias monetárias ou em qualquer lugar onde você precisa de aritmética decimal exata, use BigDecimal:

import java.math.BigDecimal;

BigDecimal sum = new BigDecimal("0.1").add(new BigDecimal("0.2"));
System.out.println(sum);   // 0.3

Sempre passe strings para new BigDecimal(...). O construtor com double reintroduziria a inexatidão binária.

Valores especiais de ponto flutuante

double tem três valores que não são números comuns:

double posInf = Double.POSITIVE_INFINITY;
double negInf = Double.NEGATIVE_INFINITY;
double nan = Double.NaN;

System.out.println(1.0 / 0);          // Infinity
System.out.println(-1.0 / 0);         // -Infinity
System.out.println(0.0 / 0);          // NaN

System.out.println(nan == nan);       // false — NaN compares unequal to everything
System.out.println(Double.isNaN(nan)); // true

Use Double.isNaN(x) para testar NaN; == não funcionará.

As classes wrapper

Cada primitivo tem um wrapper correspondente: Byte, Short, Integer, Long, Float, Double. Os wrappers estendem a classe abstrata Number. Você precisa deles quando:

  • Usar coleções que armazenam objetos: List<Integer>, Map<String, Double>.
  • Converter de strings: Integer.parseInt("42"), Double.parseDouble("3.14").
  • Converter para um tipo numérico diferente via .intValue(), .doubleValue(), etc.

Java faz autoboxing entre primitivo e wrapper automaticamente:

List<Integer> ids = new ArrayList<>();
ids.add(42);            // autobox: int → Integer
int first = ids.get(0); // unbox: Integer → int

BigInteger e BigDecimal

Quando os números podem ser maiores que long ou você precisa de precisão decimal:

import java.math.BigInteger;

BigInteger huge = new BigInteger("123456789012345678901234567890");
huge.multiply(huge);

BigDecimal price = new BigDecimal("19.95");
BigDecimal tax = price.multiply(new BigDecimal("0.07"));

São mais lentos que os primitivos, mas para os casos que precisam deles, é a troca certa.

Uma demonstração

java— editable, runs on the server

O que vem a seguir

  • Java MathMath.abs, Math.round, Math.pow e o restante do kit de ferramentas numérico.
  • Java Operators — como os operadores aritméticos, de comparação e bit a bit se comportam nesses tipos.
  • Java Booleans — o tipo de dois valores do Java, com muito menos detalhes.

Prática

Prática
Qual tipo é mais adequado para representar uma quantia em dinheiro em Java?
Qual tipo é mais adequado para representar uma quantia em dinheiro em Java?
Was this page helpful?