tipo primitivo | Tamanho na memória | Faixa de valor |
---|---|---|
byte | 8 bits | -128 a 127 |
curto | 16 bits | -32768 a 32767 |
Caracteres | 16 bits | 0 a 65536 |
int | 32 bits | -2147483648 a 2147483647 |
longo | 64 bits | -9223372036854775808 a 9223372036854775807 |
flutuador | 32 bits | (2 elevado a -149) para ((2 elevado a -23) * 2 elevado a 127) |
dobro | 64 bits | (-2 elevado a 63) para ((2 elevado a 63) - 1) |
boleano | 8 (quando usado em arrays), 32 (quando não usado em arrays) | verdadeiro ou falso |
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigDecimal decimal = new BigDecimal("123.444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444");
System.out.println(decimal);
}
}
Passar uma string para o construtor é apenas uma opção possível. Aqui usamos strings, pois nossos números excedem os valores máximos para long e double , e precisamos sim de alguma forma explicar para o compilador qual número queremos criar :) 1111111111111111111111111111111111111111111111111111111111111111111111111 para o construtor não funcionará: Java tentará colocar o número passado em um dos tipos de dados primitivos, mas não se encaixará em nenhum deles. Por isso usar uma string para passar o número desejado é uma boa opção. Ambas as classes podem extrair automaticamente valores numéricos das strings passadas. Outro ponto importante a ser lembrado ao trabalhar com classes de números grandes é que seus objetos são imutáveis ( Immutable ). Você já está familiarizado com a imutabilidade graças à sua experiência com a classe String e as classes wrapper para tipos primitivos (Integer, Long, etc.).
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
integer.add(BigInteger.valueOf(33333333));
System.out.println(integer);
}
}
Saída do console:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Como seria de esperar, nosso número não mudou. Para realizar a operação de adição, deve-se criar um novo objeto para receber o resultado da operação.
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigInteger result = integer.add(BigInteger.valueOf(33333333));
System.out.println(result);
}
}
Saída do console:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
Veja, agora tudo funciona como deveria :) A propósito, você notou como a operação de adição parece incomum?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
Este é outro ponto importante. Classes de números grandes não usam os operadores + - * /. Em vez disso, eles fornecem um conjunto de métodos. Vamos conhecer os principais (como sempre, você encontra a lista completa dos métodos na documentação do Oracle: aqui e aqui ).
-
métodos para operações aritméticas: adicionar() , subtrair() , multiplicar() , dividir() . Esses métodos são usados para realizar adição, subtração, multiplicação e divisão, respectivamente.
-
doubleValue() , intValue() , floatValue() , longValue() , etc. são usados para converter um grande número em um dos tipos primitivos de Java. Tenha cuidado ao usar esses métodos. Não se esqueça das diferenças no tamanho do bit!
import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); long result = integer.longValue(); System.out.println(result); } }
Saída do console:
8198552921648689607
-
min() e max() permitem encontrar o valor mínimo e máximo de dois números grandes.
Observe que esses métodos não são estáticos!import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); BigInteger integer2 = new BigInteger("222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"); System.out.println(integer.max(integer2)); } }
Saída do console:
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
Comportamento de arredondamento BigDecimal
Este tópico tem sua própria seção separada, pois arredondar números grandes e configurar o comportamento de arredondamento não são tão simples. Você pode usar o método setScale() para definir o número de casas decimais para um BigDecimal . Por exemplo, suponha que queremos que o número 111,5555555555 tenha três dígitos após o ponto decimal. Porém, não podemos conseguir o que queremos passando o número 3 como argumento para o método setScale() . Como mencionado acima, BigDecimalé para representar números com requisitos rígidos de precisão computacional. Em sua forma atual, nosso número tem 10 dígitos após o ponto decimal. Queremos descartar 7 deles e manter apenas 3. Assim, além do número 3, devemos passar pelo modo de arredondamento. BigDecimal tem um total de 8 modos de arredondamento. Isso é muito! Mas se você realmente precisar ajustar a precisão de seus cálculos, terá tudo o que precisa. Então, aqui estão os 8 modos de arredondamento oferecidos pelo BigDecimal :-
ROUND_CEILING — arredonda para cima
111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
-
ROUND_DOWN — arredonda para zero
111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
-
ROUND_FLOOR — arredonda para baixo
111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555
-
ROUND_HALF_UP — arredonda para cima se o número após a vírgula >= 0,5
0.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN — arredonda para cima se o número após a vírgula > 0,5
0.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5 0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
-
ROUND_HALF_EVEN — o arredondamento depende do número à esquerda do ponto decimal. Se o número à esquerda for par, o arredondamento será para baixo. Se o número à esquerda da vírgula for ímpar, o arredondamento será superior.
2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2
O número à esquerda da casa decimal é 2 (par). O número é arredondado para baixo. Queremos 0 casas decimais, então o resultado é 2.
3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4
O número à esquerda do ponto decimal é 3 (ímpar). O número é arredondado para cima. Queremos 0 casas decimais, então o resultado é 4.
-
ROUND_UNNECCESSARY — Este modo é usado quando você deve passar um modo de arredondamento para um método, mas o número não precisa ser arredondado. Se você tentar arredondar um número com o modo ROUND_UNNECCESSARY definido, uma ArithmeticException será lançada.
3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP — arredonda a partir de zero.
111.5551 -> setScale(3, ROUND_UP) -> 111.556
Comparando números grandes
Isso também é importante. Você deve se lembrar que usamos o método equals() para comparar objetos em Java. A implementação é fornecida pela própria linguagem (para classes Java padrão) ou substituída pelo programador. Mas no caso de objetos BigDecimal , não é recomendado usar o método equals() para comparações. Isso porque o método BigDecimal.equals() retorna true somente se os 2 números tiverem o mesmo valor e escala: Vamos comparar o comportamento do método equals() para as classes Double e BigDecimal :
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
Double a = 1.5;
Double b = 1.50;
System.out.println(a.equals(b));
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.equals(y));
}
}
Saída do console:
true
false
Como você pode ver, para BigDecimal , os números 1,5 e 1,50 acabaram sendo desiguais! Isso ocorreu precisamente devido às especificidades da implementação do método equals() na classe BigDecimal . Para uma comparação mais precisa de dois objetos BigDecimal , é melhor usar o método compareTo() :
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.compareTo(y));
}
}
Saída do console:
0
O método compareTo() retornou 0, o que significa que 1,5 e 1,50 são iguais. E esse é o resultado que esperávamos! :) Isso conclui nossa lição de hoje. Agora é hora de voltar às tarefas! :)
GO TO FULL VERSION