tipo primitivo | Tamaño en memoria | Rango de valores |
---|---|---|
byte | 8 bits | -128 a 127 |
corto | 16 bits | -32768 a 32767 |
carbonizarse | 16 bits | 0 a 65536 |
En t | 32 bits | -2147483648 al 2147483647 |
largo | 64 bits | -9223372036854775808 al 9223372036854775807 |
flotar | 32 bits | (2 elevado a -149) a ((2 elevado a -23) * 2 elevado a 127) |
doble | 64 bits | (-2 elevado a 63) a ((2 elevado a 63) - 1) |
booleano | 8 (cuando se usa en matrices), 32 (cuando no se usa en matrices) | verdadero o 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);
}
}
Pasar una cadena al constructor es solo una opción posible. Aquí usamos cadenas, porque nuestros números exceden los valores máximos para long y double , y necesitamos alguna forma de explicarle al compilador qué número queremos crear :) Simplemente pasando el número 1111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111 al constructor no funcionará: Java intentará meter el número pasado en uno de los tipos de datos primitivos, pero no encajará en ninguno de ellos. Es por eso que usar una cadena para pasar el número deseado es una buena opción. Ambas clases pueden extraer automáticamente valores numéricos de las cadenas pasadas. Otro punto importante a recordar cuando se trabaja con clases de números grandes es que sus objetos son inmutables ( Immutable ). Ya estás familiarizado con la inmutabilidad gracias a tu experiencia con la clase String y las clases contenedoras 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);
}
}
Salida de la consola:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Como era de esperar, nuestro número no ha cambiado. Para realizar la operación de suma, debe crear un nuevo objeto para recibir el resultado de la operación.
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);
}
}
Salida de la consola:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
Mira, ahora todo funciona como debería :) Por cierto, ¿te diste cuenta de lo inusual que se ve la operación de suma?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
Este es otro punto importante. Las clases de números grandes no usan los operadores + - * /. En su lugar, proporcionan un conjunto de métodos. Conozcamos los principales (como siempre, puede encontrar una lista completa de métodos en la documentación de Oracle: aquí y aquí ).
-
métodos para operaciones aritméticas: sumar() , restar() , multiplicar() , dividir() . Estos métodos se utilizan para realizar sumas, restas, multiplicaciones y divisiones, respectivamente.
-
doubleValue() , intValue() , floatValue() , longValue() , etc. se utilizan para convertir un gran número en uno de los tipos primitivos de Java. Tenga cuidado al usar estos métodos. ¡No te olvides de las diferencias en el tamaño de los bits!
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); } }
Salida de la consola:
8198552921648689607
-
min() y max() te permiten encontrar el valor mínimo y máximo de dos números grandes.
¡Tenga en cuenta que estos métodos no son 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)); } }
Salida de la consola:
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
Comportamiento de redondeo BigDecimal
Este tema tiene su propia sección separada, ya que redondear números grandes y configurar el comportamiento de redondeo no es tan simple. Puede usar el método setScale() para establecer la cantidad de lugares decimales para un BigDecimal . Por ejemplo, supongamos que queremos que el número 111.5555555555 tenga tres dígitos después del punto decimal. Sin embargo, no podemos lograr lo que queremos pasando el número 3 como argumento al método setScale() . Como se mencionó anteriormente, BigDecimales para representar números con estrictos requisitos de precisión computacional. En su forma actual, nuestro número tiene 10 dígitos después del punto decimal. Queremos eliminar 7 de ellos y quedarnos solo con 3. En consecuencia, además del número 3, debemos pasar el modo de redondeo. BigDecimal tiene un total de 8 modos de redondeo. ¡Eso es mucho! Pero si realmente necesita afinar la precisión de sus cálculos, tendrá todo lo que necesita. Entonces, aquí están los 8 modos de redondeo que ofrece BigDecimal :-
ROUND_CEILING — redondea hacia arriba
111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
-
ROUND_DOWN — redondea hacia cero
111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
-
ROUND_FLOOR — redondea hacia abajo
111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555
-
ROUND_HALF_UP — redondea hacia arriba si el número después del punto decimal >= 0.5
0.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN — redondea hacia arriba si el número después del punto decimal > 0.5
0.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5 0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
-
ROUND_HALF_EVEN : el redondeo depende del número a la izquierda del punto decimal. Si el número de la izquierda es par, el redondeo será hacia abajo. Si el número a la izquierda del punto decimal es impar, el redondeo será hacia arriba.
2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2
El número a la izquierda del lugar decimal es 2 (par). El número se redondea hacia abajo. Queremos 0 decimales, por lo que el resultado es 2.
3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4
El número a la izquierda del punto decimal es 3 (impar). El número se redondea. Queremos 0 decimales, por lo que el resultado es 4.
-
ROUND_UNNECCESSARY : este modo se usa cuando debe pasar un modo de redondeo a un método, pero no es necesario redondear el número. Si intenta redondear un número con el modo ROUND_UNNECCESSARY establecido, se lanza una ArithmeticException.
3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP — redondea desde cero.
111.5551 -> setScale(3, ROUND_UP) -> 111.556
Comparar números grandes
Esto también es importante. Recordará que usamos el método equals() para comparar objetos en Java. La implementación la proporciona el propio lenguaje (para las clases estándar de Java) o el programador la anula. Pero en el caso de objetos BigDecimal , no se recomienda usar el método equals() para realizar comparaciones. Esto se debe a que el método BigDecimal.equals() devuelve verdadero solo si los 2 números tienen el mismo valor y escala: Comparemos el comportamiento del método equals() para las clases Double y 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));
}
}
Salida de la consola:
true
false
Como puede ver, para BigDecimal , ¡los números 1.5 y 1.50 resultaron ser desiguales! Esto se debió precisamente a los detalles de la implementación del método equals() en la clase BigDecimal . Para una comparación más precisa de dos objetos BigDecimal , es mejor usar el 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));
}
}
Salida de la consola:
0
El método compareTo() devolvió 0, lo que significa que 1,5 y 1,50 son iguales. ¡Y este es el resultado que esperábamos! :) Eso concluye nuestra lección de hoy. ¡Ahora es el momento de volver a las tareas! :)
GO TO FULL VERSION