Em Java, um valor ou é uma referência a um objeto ou pertence a um dos oito tipos pri-
mitivos mostrados na Tabela 1.
Seis dos tipos primitivos são tipos numéricos, quatro deles para inteiros e dois para números de ponto fl utuante.
Cada um dos tipos inteiros possui um intervalo diferente – o Tópico Avançado 4.2 explica por que os limites de intervalo estão relacionados a potências de dois. No geral, você utilizará o tipo int para quantidades inteiras. Mas, ocasionalmente, cálculos que envolvem inteiros podem causar overfl ow, ou “estouro”. Isso acon- tece se o resultado de um cálculo exceder o intervalo do tipo numé- rico. Por exemplo:
int n = 1000000;
System.out.println(n * n); // Imprime –727379968
O produto n * n é 1012, o que é maior que o maior inteiro (aproximadamente 2 · 109). O resultado está truncado para caber em um int, produzindo um valor completamente erra- do. Infelizmente, não há nenhum aviso quando um estouro de inteiro acontece.
Se encontrar esse problema, a correção mais simples é utilizar o tipo long. O Tópico Avançado 4.1 mostra como utilizar o tipo BigInteger de precisão arbitrária na imprová- vel situação de até mesmo o tipo long estourar.
Java possui oito tipos primitivos, incluindo quatro tipos de inteiros e dois de ponto fl utuante.
Um cálculo numérico causa overfl ow se o resultado estiver fora do intervalo do tipo numérico.
4.1 Tipos numéricos 146
SINTAXE 4.1: Coerção (Typecasting) 148
TÓPICOAVANÇADO 4.1: Números grandes
TÓPICOAVANÇADO 4.2: Números binários
FATOALEATÓRIO 4.1: O bug de ponto fl utuante do Pentium
4.2 Constantes 149
SINTAXE 4.2: Defi nição de constante 151
DICADEQUALIDADE 4.1: Não utilize números mágicos 154
DICADEQUALIDADE 4.2: Escolha nomes descritivos para variáveis 154
4.3 Atribuição, incremento e decremento 155
DICADEPRODUTIVIDADE 4.1: Evite um leiaute instável
TÓPICOAVANÇADO 4.3: Combinando atribuição e aritmética
4.4 Operações aritméticas e funções matemáticas 156
ERROCOMUM 4.1: Divisão de inteiros 159
ERROCOMUM 4.2: Parênteses desbalanceados 160
DICADEQUALIDADE 4.3: Espaço em branco 160
DICADEQUALIDADE 4.4: Fatorando código comum 161
4.5 Chamando métodos estáticos 161
SINTAXE 4.3: Chamada de método estático 162
ERROCOMUM 4.3: Erros de arredondamento 163
COMOFAZER 4.1: Realizando cálculos 163 4.6 Strings 166
DICADEPRODUTIVIDADE 4.2: Lendo relatórios de exceções 168
TÓPICOAVANÇADO 4.4: Seqüências de escape
TÓPICOAVANÇADO 4.5: Strings e o tipo char
FATOALEATÓRIO 4.2: Alfabetos internacionais 4.7 Lendo a entrada 169
TÓPICOAVANÇADO 4.6: Formatando números
TÓPICOAVANÇADO 4.7: Utilizando caixas de diálogo para entrada e saída
O estouro normalmente não é um problema para números de ponto fl utuante de du- pla precisão. O tipo double tem um intervalo de aproximadamente ±10308 e 15 dígitos signifi cativos. Mas você quer evitar o tipo fl oat – ele tem menos de 7 dígitos signifi cati- vos. (Alguns programadores utilizam fl oat para salvar em memória, se precisarem arma- zenar um conjunto muito grande de números sem muita precisão.)
Erros de arredondamento são uma questão mais séria com va-
lores de ponto fl utuante. Erros de arredondamento podem ocorrer quando você converte entre números binários e decimais ou entre números inteiros e números de ponto fl utuante. Quando um valor não pode ser convertido exatamente, ele é arredondado para o nú- mero mais próximo. Pense neste exemplo:
double f = 4.35;
System.out.println(100 * f); // Imprime 434.99999999999994.
Esse problema é causado porque computadores representam números no sistema biná- rio. No sistema de números binários, não há representação exata da fração 1/10, assim como não há representação exata da fração 1/3 = 0,33333 no sistema de números deci- mais. (Veja o Tópico Avançado 4.2 para informações adicionais.)
Por essa razão, o tipo double não é apropriado para cálculos fi nanceiros. Neste livro, continuaremos a utilizar valores double para saldos bancários e outros valores monetá- rios para que possamos manter nossos programas o mais simples possível. Entretanto, programas profi ssionais precisam utilizar os tipos BigDecimal para esse propósito – veja o Tópico Avançado 4.1.
Erros de arredondamento ocorrem quando uma conversão exata entre números não é possível.
Tabela 1 Tipos primitivos
Tipo Descrição Tamanho
int Tipo inteiro, com intervalo –2.147.483.648. . . 2.147.483.647 (cerca de 2 bilhões)
4 bytes byte Tipo que descreve um único byte, com intervalo –128. . . 127 1 byte short Tipo inteiro curto, com intervalo –32768 . . . 32767 2 bytes
long Tipo inteiro longo, com intervalo
–9.223.372.036.854.775.808 . . . 9.223.372.036.854.775.807
8 bytes double Tipo ponto fl utuante de dupla precisão, com um intervalo de
aproximadamente ±10308 e aproximadamente 15 dígitos decimais signifi cativos
8 bytes
fl oat Tipo ponto fl utuante de precisão simples, com um intervalo de aproximadamente ±1038 e aproximadamente 7 dígitos decimais
signifi cativos
4 bytes
char Tipo caractere, representando unidades de código no esquema de codifi cação Unicode (ver Tópico avançado 4.5)
2 bytes boolean Tipo com dois valores exclusivos, false ou true (ver Capítulo 5) 1 bit
Em Java, é válido atribuir um valor do tipo inteiro a uma variável de ponto fl utuante: int dollars = 100;
double balance = dollars; // OK
Mas a atribuição oposta é um erro: você não pode atribuir uma expressão de ponto fl utu- ante a uma variável do tipo inteiro.
double balance = 13.75;
int dollars = balance; // Erro
Para superar esse problema, você pode converter o valor de ponto fl utuante em um inteiro usando uma coerção (ou typecasting):
int dollars = (int) balance;
A coerção (int) converte o valor de ponto fl utuante balance em um inteiro descartando a parte fracionária. Por exemplo, se balance for 13.75, então dollars será confi gurado como 13.
A coerção instrui o compilador de que você concorda com a
perda de informações, nesse caso, com a perda da parte fracioná-
ria. Você também pode aplicar uma coerção a outros tipos, como (fl oat) ou (byte).
Se quiser arredondar um número de ponto fl utuante para o número inteiro mais próximo, utilize o método Math.round. Esse método retorna um inteiro long, pois números de ponto fl utuante grandes não podem ser armazenados em um int.
long rounded = Math.round(balance);
Se balance for 13.75, então rounded será confi gurado como 14.