Java Language
BigInteger
Buscar..
Introducción
La clase BigInteger
se usa para operaciones matemáticas que involucran enteros grandes con magnitudes demasiado grandes para tipos de datos primitivos. Por ejemplo, 100 factorial es 158 dígitos, mucho más grande de lo que puede representar un long
. BigInteger
proporciona análogos a todos los operadores enteros primitivos de Java y todos los métodos relevantes de java.lang.Math
, así como algunas otras operaciones.
Sintaxis
- BigInteger variable_name = new BigInteger ("12345678901234567890"); // un entero decimal como una cadena
- BigInteger variable_name = new BigInteger ("1010101101010101010100110001100111010110001111100001011010010", 2) // un entero binario como una cadena
- BigInteger variable_name = new BigInteger ("ab54a98ceb1f0800", 16) // un entero hexadecimal como una cadena
- BigInteger variable_name = new BigInteger (64, new Random ()); // un generador de números pseudoaleatorios que suministra 64 bits para construir un entero
- BigInteger variable_name = new BigInteger (new byte [] {0, -85, 84, -87, -116, -21, 31, 10, -46}); // firmó la representación complementaria de dos de un entero (big endian)
- BigInteger variable_name = new BigInteger (1, nuevo byte [] {- 85, 84, -87, -116, -21, 31, 10, -46}); // representación de complemento de dos sin signo de un entero positivo (big endian)
Observaciones
BigInteger
es inmutable. Por lo tanto no puedes cambiar su estado. Por ejemplo, lo siguiente no funcionará ya que la sum
no se actualizará debido a la inmutabilidad.
BigInteger sum = BigInteger.ZERO;
for(int i = 1; i < 5000; i++) {
sum.add(BigInteger.valueOf(i));
}
Asigna el resultado a la variable sum
para que funcione.
sum = sum.add(BigInteger.valueOf(i));
La documentación oficial de BigInteger
indica que las implementaciones de BigInteger
deben admitir todos los enteros entre -2 2147483647 y 2 2147483647 (exclusivo). ¡Esto significa que BigInteger
puede tener más de 2 mil millones de bits!
Inicialización
La clase java.math.BigInteger
proporciona operaciones análogas a todos los operadores de enteros primitivos de Java y para todos los métodos relevantes de java.lang.Math
. Como el paquete java.math
no está disponible automáticamente, es posible que tenga que importar java.math.BigInteger
antes de poder usar el nombre de clase simple.
Para convertir valores long
o int
en BigInteger
use:
long longValue = Long.MAX_VALUE;
BigInteger valueFromLong = BigInteger.valueOf(longValue);
o, para enteros:
int intValue = Integer.MIN_VALUE; // negative
BigInteger valueFromInt = BigInteger.valueOf(intValue);
que ampliarán el intValue
número entero de largo, utilizando la extensión bit de signo para los valores negativos, por lo que los valores negativos permanecerán negativo.
Para convertir una String
numérica a BigInteger
use:
String decimalString = "-1";
BigInteger valueFromDecimalString = new BigInteger(decimalString);
El siguiente constructor se utiliza para traducir la representación de cadena de un BigInteger
en el radix especificado en un BigInteger
.
String binaryString = "10";
int binaryRadix = 2;
BigInteger valueFromBinaryString = new BigInteger(binaryString , binaryRadix);
Java también admite la conversión directa de bytes a una instancia de BigInteger
. Actualmente solo se puede usar la codificación big endian firmada y sin firmar:
byte[] bytes = new byte[] { (byte) 0x80 };
BigInteger valueFromBytes = new BigInteger(bytes);
Esto generará una instancia de BigInteger
con valor -128 ya que el primer bit se interpreta como el bit de signo.
byte[] unsignedBytes = new byte[] { (byte) 0x80 };
int sign = 1; // positive
BigInteger valueFromUnsignedBytes = new BigInteger(sign, unsignedBytes);
Esto generará una instancia de BigInteger
con valor 128, ya que los bytes se interpretan como un número sin firma y el signo se establece explícitamente en 1, un número positivo.
Hay constantes predefinidas para valores comunes:
-
BigInteger.ZERO
- valor de "0". -
BigInteger.ONE
- valor de "1". -
BigInteger.TEN
- valor de "10".
También hay BigInteger.TWO
(valor de "2"), pero no puedes usarlo en tu código porque es private
.
Comparando BigIntegers
Puede comparar BigIntegers
igual que compara String
u otros objetos en Java.
Por ejemplo:
BigInteger one = BigInteger.valueOf(1);
BigInteger two = BigInteger.valueOf(2);
if(one.equals(two)){
System.out.println("Equal");
}
else{
System.out.println("Not Equal");
}
Salida:
Not Equal
Nota:
En general, no use el operador ==
para comparar BigIntegers
- operador
==
: compara referencias; es decir, si dos valores se refieren al mismo objeto - Método
equals()
: compara el contenido de dos BigIntegers.
Por ejemplo, BigIntegers no debe compararse de la siguiente manera:
if (firstBigInteger == secondBigInteger) {
// Only checks for reference equality, not content equality!
}
Si lo hace, puede provocar un comportamiento inesperado, ya que el operador ==
solo comprueba la igualdad de referencia. Si ambos BigIntegers contienen el mismo contenido, pero no se refieren al mismo objeto, esto fallará. En su lugar, compare BigIntegers utilizando los métodos equals
, como se explicó anteriormente.
También puede comparar su BigInteger
con valores constantes como 0,1,10.
por ejemplo:
BigInteger reallyBig = BigInteger.valueOf(1);
if(BigInteger.ONE.equals(reallyBig)){
//code when they are equal.
}
También puede comparar dos BigIntegers usando el compareTo()
, como sigue: compareTo()
devuelve 3 valores.
- 0: Cuando ambos son iguales .
- 1: Cuando el primero es mayor que el segundo (el que está entre paréntesis).
- -1: Cuando el primero es menor que el segundo.
BigInteger reallyBig = BigInteger.valueOf(10);
BigInteger reallyBig1 = BigInteger.valueOf(100);
if(reallyBig.compareTo(reallyBig1) == 0){
//code when both are equal.
}
else if(reallyBig.compareTo(reallyBig1) == 1){
//code when reallyBig is greater than reallyBig1.
}
else if(reallyBig.compareTo(reallyBig1) == -1){
//code when reallyBig is less than reallyBig1.
}
Ejemplos de operaciones matemáticas de BigInteger
BigInteger se encuentra en un objeto inmutable, por lo que debe asignar los resultados de cualquier operación matemática a una nueva instancia de BigInteger.
Adición: 10 + 10 = 20
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("10");
BigInteger sum = value1.add(value2);
System.out.println(sum);
salida: 20
Sustracción: 10 - 9 = 1
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("9");
BigInteger sub = value1.subtract(value2);
System.out.println(sub);
salida: 1
División: 10/5 = 2
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("5");
BigInteger div = value1.divide(value2);
System.out.println(div);
salida: 2
División: 17/4 = 4
BigInteger value1 = new BigInteger("17");
BigInteger value2 = new BigInteger("4");
BigInteger div = value1.divide(value2);
System.out.println(div);
salida: 4
Multiplicación: 10 * 5 = 50
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("5");
BigInteger mul = value1.multiply(value2);
System.out.println(mul);
salida: 50
Potencia: 10 ^ 3 = 1000
BigInteger value1 = new BigInteger("10");
BigInteger power = value1.pow(3);
System.out.println(power);
salida: 1000
Resto: 10% 6 = 4
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("6");
BigInteger power = value1.remainder(value2);
System.out.println(power);
salida: 4
GCD: el divisor común más grande (GCD) para 12
y 18
es 6
.
BigInteger value1 = new BigInteger("12");
BigInteger value2 = new BigInteger("18");
System.out.println(value1.gcd(value2));
Salida: 6
Máximo de dos BigIntegers:
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("11");
System.out.println(value1.max(value2));
Salida: 11
Mínimo de dos BigIntegers:
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("11");
System.out.println(value1.min(value2));
Salida: 10
Operaciones de lógica binaria en BigInteger
BigInteger admite las operaciones lógicas binarias que también están disponibles para los tipos de Number
. Al igual que con todas las operaciones, se implementan llamando a un método.
Binario o
BigInteger val1 = new BigInteger("10");
BigInteger val2 = new BigInteger("9");
val1.or(val2);
Salida: 11 (que es equivalente a
10 | 9
)
Binario y
BigInteger val1 = new BigInteger("10");
BigInteger val2 = new BigInteger("9");
val1.and(val2);
Salida: 8 (que es equivalente a
10 & 9
)
Xor binario:
BigInteger val1 = new BigInteger("10");
BigInteger val2 = new BigInteger("9");
val1.xor(val2);
Salida: 3 (que es equivalente a
10 ^ 9
)
Giro a la derecha:
BigInteger val1 = new BigInteger("10");
val1.shiftRight(1); // the argument be an Integer
Salida: 5 (equivalente a
10 >> 1
)
Shift izquierdo:
BigInteger val1 = new BigInteger("10");
val1.shiftLeft(1); // here parameter should be Integer
Salida: 20 (equivalente a
10 << 1
)
Inversión binaria (no):
BigInteger val1 = new BigInteger("10");
val1.not();
Salida: 5
NAND (y no): *
BigInteger val1 = new BigInteger("10");
BigInteger val2 = new BigInteger("9");
val1.andNot(val2);
Salida: 7
Generando BigIntegers aleatorios
La clase BigInteger
tiene un constructor dedicado a generar BigIntegers
aleatorios, dada una instancia de java.util.Random
y un int
que especifica cuántos bits tendrá el BigInteger
. Su uso es bastante simple: cuando se llama al constructor BigInteger(int, Random)
siguiente manera:
BigInteger randomBigInt = new BigInteger(bitCount, sourceOfRandomness);
luego terminarás con un BigInteger
cuyo valor está entre 0 (inclusive) y 2 bitCount
(exclusivo).
Esto también significa que el new BigInteger(2147483647, sourceOfRandomness)
puede devolver todo BigInteger
positivo dado suficiente tiempo.
¿Cuál será la sourceOfRandomness
La sourceOfRandomness
depende de usted. Por ejemplo, un new Random()
es suficientemente bueno en la mayoría de los casos:
new BigInteger(32, new Random());
Si está dispuesto a renunciar a la velocidad para obtener números aleatorios de mayor calidad, puede usar un new SecureRandom ()
lugar:
import java.security.SecureRandom;
// somewhere in the code...
new BigInteger(32, new SecureRandom());
¡Incluso puede implementar un algoritmo sobre la marcha con una clase anónima! Tenga en cuenta que el despliegue de su propio algoritmo RNG lo terminará con una aleatoriedad de baja calidad , por lo que siempre asegúrese de usar un algoritmo que se demuestre que sea decente a menos que desee que los BigInteger
resultantes sean predecibles.
new BigInteger(32, new Random() {
int seed = 0;
@Override
protected int next(int bits) {
seed = ((22695477 * seed) + 1) & 2147483647; // Values shamelessly stolen from Wikipedia
return seed;
}
});