boolean
e char
, elas são divididas nos seguintes tipos:
- inteiros:
byte
,short
,int
elong
; - ponto flutuante (também chamados de números reais):
float
edouble
.
long
, com um intervalo de -9223372036854775808 a 9223372036854775807. Dos números de ponto flutuante, , double
com um intervalo de 1,7e-308 a 1,7e+308. Você pode ler mais sobre números reais neste artigo . Mas e se precisarmos armazenar números que excedam o intervalo aceitável? Neste caso, precisaremos BigInteger
de e BigDecimal
.
BigInteger em Java
A classe JavaBigInteger
é usada como um análogo para valores inteiros de comprimento arbitrário que não possuem o limite de comprimento de 64 bits. Além disso, é descendente da classe Number
, como wrappers padrão para tipos simples numéricos - Integer
, Long
, Byte
e Double
assim por diante - portanto, possui implementações de métodos que levam a tipos simples:
BigInteger value = new BigInteger("32145");
int intValue = value.intValue();//32145
long longValue = value.longValue();//32145
double doubleValue = value.doubleValue();//32145.0
Imediatamente vemos a criação de tal objeto BigInteger
com nosso valor sendo passado para o construtor, mas em formato string. Vale ressaltar que ele conta com mais de um designer, mas para todas as ocasiões. Se os tipos primitivos não acomodarem a quantidade total de dados de BigInteger
, os dados serão truncados para o intervalo desse tipo primitivo. Mas, ao mesmo tempo, existem análogos desses métodos ( intValueExact()
, longValueExact()
etc.), com a única diferença de que se o tipo simples para o qual a conversão está ocorrendo não acomodar o intervalo de dados, uma ArithmeticException será lançada .
Constantes BigInteger
Para uso interno, a classe possui constantes:BigInteger.ZERO
BigInteger.ONE
BigInteger.TEN
Estes são objetos constantes BigInteger
com valores, respectivamente 0
, 1
e 10
.
Métodos BigInteger
Uma das principais características desta classe é que ela está repleta de métodos que implementam operações aritméticas padrão em Java. Por exemplo:-
operações de soma:
BigInteger firstValue = new BigInteger("37995"); BigInteger secondValue = new BigInteger("35466"); BigInteger resultValue = firstValue.add(secondValue);//73461
-
operações de multiplicação:
BigInteger firstValue = new BigInteger("37995"); BigInteger secondValue = new BigInteger("35466"); BigInteger resultValue = firstValue.multiply(secondValue);//1347530670
-
operações de encontrar o resto ao dividir um número por outro:
BigInteger firstValue = new BigInteger("37995"); BigInteger secondValue = new BigInteger("35466"); BigInteger resultValue = firstValue.remainder(secondValue);//2529
-
obtendo o valor absoluto de um número (ou seja, módulo, sem sinal):
BigInteger firstValue = new BigInteger("-37995"); BigInteger resultValue = firstValue.abs();//37995
-
operações com cálculo mod :
BigInteger firstValue = new BigInteger("-34"); BigInteger secondValue = new BigInteger("5"); BigInteger resultValue = firstValue.mod(secondValue); //1
-
obtendo um número aleatório e especificando o número de bits que o valor resultante usará:
BigInteger firstValue = BigInteger.probablePrime(8, new Random());//211 BigInteger secondValue = BigInteger.probablePrime(16, new Random());//42571
-
operações de deslocamento bit a bit (este >> n)
Deslocar para a esquerda:
BigInteger firstValue = new BigInteger("5"); BigInteger firstResultValue = firstValue.shiftLeft(3);//40
Deslocar para a direita:
BigInteger secondValue = new BigInteger("34"); BigInteger secondResultValue = secondValue.shiftRight(2); //8
BigDecimal em Java
Quando precisamos de um número real de comprimento arbitrário, a classe Java é usada -BigDecimal
. Via de regra, é utilizado para trabalhar com finanças ao invés de double
, pois oferece mais opções de customização. Assim como e BigInteger
, BigDecimal
é descendente de uma classe Number
e possui métodos que retornam o valor de um objeto como um tipo primitivo específico:
BigDecimal value = new BigDecimal(35563.3);
long longValue = value.longValue();//35563
double doubleValue = value.doubleValue();//35563.3
Como podemos ver ao reduzir para long
, resta apenas a parte inteira e as casas decimais são descartadas.
Construtores BigDecimal
Vamos dar uma olhada mais de perto nos construtoresBigDecimal
, já que a classe possui uma seleção muito mais ampla deles. Existem construtores que permitem definir o valor de um objeto de diferentes maneiras (passando int
, long
, double
e String
até BigInteger
), e há aqueles que permitem isso. defina as configurações do objeto criado (métodos de arredondamento, número de casas decimais):
BigDecimal firstValue = new BigDecimal("455656.545");//455656.545
Tudo está claro aqui, definimos diretamente o valor e o número de casas decimais que queremos ver.
BigDecimal secondValue = new BigDecimal(3445.54);//3445.5399999999999636202119290828704833984375
Os resultados deste construtor podem ser bastante imprevisíveis, porque estamos especificando um double, que por natureza é um tipo muito ambíguo. Portanto, geralmente é recomendado usar em um construtor String
.
BigDecimal thirdValue = new BigDecimal(3445.554645675444, MathContext.DECIMAL32);//3445.555
Definimos double
, mas ao mesmo tempo também definimos um parâmetro que descreve a regra de arredondamento (que contém o número de casas decimais e o algoritmo de arredondamento).
char[] arr = new String("455656.545").toCharArray();
BigDecimal fourthValue = new BigDecimal(arr, 2, 6);//5656.5
Definimos um array de caracteres de qual elemento obtemos os valores do objeto e quantos desses elementos obtemos.
BigDecimal fifthValue = new BigDecimal(new BigInteger("44554"), 3);//44.554
Pegamos um objeto já existente BigInteger
e definimos o número de casas decimais.
Métodos BigDecimais
A classeBigDecimal
também contém métodos para diversas operações aritméticas, mas BigInteger
não possui métodos para trabalhar com bits, como . Mesmo assim, a principal característica BigDecimal
é a flexibilidade em trabalhar com números de ponto flutuante. Vejamos algumas técnicas que nos dão o poder de dominar os números reais:
-
obtemos a precisão (número de números):
BigDecimal value = new BigDecimal("454334.34334"); int result = value.precision();//11
-
defina o número de casas decimais e a regra de arredondamento:
BigDecimal firstValue = new BigDecimal(3445.544445); BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_CEILING);//3445.545
A seguir veremos mais de perto as constantes para definir regras de arredondamento.
-
dividir
BigDecimal
por outroBigDecimal
, indicando o número necessário de casas decimais e a regra de arredondamento:BigDecimal firstValue = new BigDecimal("455656.545"); BigDecimal secondValue = new BigDecimal(3445.544445); BigDecimal result = firstValue.divide(secondValue, 2,RoundingMode.DOWN);//132.24
-
mover uma vírgula para a direita/esquerda por um certo número de casas:
BigDecimal value = new BigDecimal("455656.545"); BigDecimal firstResult = value.movePointRight (2);//45565654.5 BigDecimal secondResult = value.movePointLeft (2);//4556.56545
-
aparar zeros à direita:
BigDecimal value = new BigDecimal("45056.5000"); BigDecimal result = value.stripTrailingZeros();//45056.5
Se tivermos todos os zeros na parte real e também houver zeros na parte inteira (ou não tivermos nenhuma casa decimal), então:
BigDecimal value = new BigDecimal("450000.000"); BigDecimal result = value.stripTrailingZeros();//4.5E+5
Regras de arredondamento BigDecimal
Para definir regras de arredondamento,BigDecimal
podemos ver constantes especiais que descrevem algoritmos de arredondamento: ROUND_UP
- arredondamento de zero, arredondamento para a parte real:
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult = firstValue.setScale(1, BigDecimal.ROUND_UP );//2.6
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_UP );//-2.5
ROUND_DOWN
— arredondamento para zero, ou seja, truncamento da parte real:
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult = firstValue.setScale(1, BigDecimal.ROUND_DOWN );//2.5
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_DOWN );//-2.6
ROUND_CEILING
— arredondando para infinito positivo. Ou seja, se nosso número for positivo, então -> ROUND_UP
, se negativo, então ->ROUND_DOWN
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult = firstValue.setScale(1, BigDecimal.ROUND_CEILING);//2.6
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_CEILING);//-2.5
ROUND_FLOOR
- arredondamento para infinito negativo, ou seja, se nosso número for positivo, então -> ROUND_DOWN
, se negativo, então ->ROUND_UP
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult = firstValue.setScale(1, BigDecimal.ROUND_FLOOR);//2.5
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_FLOOR);//-2.6
Para o valor em consideração, consideraremos este número mais próximo com casa decimal truncada como o vizinho mais próximo do número em consideração. Por exemplo, 2,43 estará mais próximo de 2,4 do que 2,5, mas 2,48 estará mais próximo de 2,5. ROUND_HALF_DOWN
— arredondando para o “vizinho mais próximo”. Se ambos os vizinhos estiverem equidistantes de um valor específico, então será realizado o arredondamento para zero. Equidistante é, por exemplo, quando o número que está sendo arredondado é 5 e está à mesma distância de 0 e 10):
BigDecimal firstValue = new BigDecimal("2.58");
BigDecimal firstResult = firstValue.setScale(1, BigDecimal.ROUND_HALF_DOWN );//2.6
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_HALF_DOWN );//2.5
ROUND_HALF_UP
— modo de arredondamento para o “vizinho mais próximo”. Se ambos os vizinhos forem equidistantes, o arredondamento é feito (este é o mesmo arredondamento que aprendemos na escola):
BigDecimal firstValue = new BigDecimal("2.53");
BigDecimal firstResult = firstValue.setScale(1, BigDecimal.ROUND_HALF_UP );//2.5
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_HALF_UP );//2.6
ROUND_HALF_EVEN
— arredondamento para o “vizinho mais próximo” se ambos os vizinhos não forem equidistantes. Neste caso, se o número a ser arredondado for precedido de um número ímpar, ele é arredondado para cima, e se for par, é arredondado para baixo:
BigDecimal firstValue = new BigDecimal("2222.2225");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.222
Obtemos esse resultado porque ao arredondar, 5 olha para o número 2 anterior, e vendo que é par, arredonda para baixo. Mas se:
BigDecimal firstValue = new BigDecimal("2222.22255");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.223
Esse arredondamento aumenta, pois o último 5 olha o valor anterior e vê um número ímpar. Como resultado, o número é arredondado para 6, após o qual o próximo 6 também é arredondado. Mas o seis não olha mais para o número da esquerda, pois o número está claramente mais próximo para cima e, como resultado, os 2 últimos são aumentados em 1. ROUND_UNNECESSARY
- usado para verificar se o número não precisa ser arredondado. Ou seja, verificamos se o número possui o número necessário de casas decimais:
BigDecimal firstValue = new BigDecimal("2.55");
BigDecimal firstResult = firstValue.setScale(2, BigDecimal.ROUND_UNNECESSARY);//2.55
Está tudo bem aqui, o valor tem dois dígitos e verificamos que existem apenas dois dígitos após a vírgula. Mas se:
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_UNNECESSARY);
Então obtemos - ArithmeticException
, pois o valor que está sendo testado excede o número especificado de casas decimais. Mas se verificarmos duas casas decimais, mas na verdade existe uma, então a exceção não será lançada e os dígitos que faltam serão simplesmente complementados com zeros:
BigDecimal thirdValue = new BigDecimal("2.5");
BigDecimal thirdResult = thirdValue.setScale(3, BigDecimal.ROUND_UNNECESSARY );//2.500
Também gostaria de observar que y tem BigDecimal
constantes semelhantes às constantes BigInteger ZERO
e ONE
. TEN
Aqui está um link para a documentação . E por último: como você provavelmente notou, ao realizar operações com objetos BigInteger
e BigDecimal
, não alteramos os antigos, mas sempre obtemos novos. Isso nos diz que eles são immutable
, isto é, imutáveis após sua criação, assim como String
. Em outras palavras, todos os seus métodos não podem alterar o estado interno do objeto; no máximo, eles podem retornar um novo objeto com os parâmetros especificados pela função que estamos usando.
GO TO FULL VERSION