Java Language
BigInteger
Ricerca…
introduzione
La classe BigInteger
viene utilizzata per operazioni matematiche che coinvolgono numeri interi grandi con grandezze troppo grandi per tipi di dati primitivi. Ad esempio 100-factorial è composto da 158 cifre, molto più grandi di quelle long
. BigInteger
fornisce analoghi a tutti gli operatori di interi primitivi di Java e tutti i metodi pertinenti di java.lang.Math
e alcune altre operazioni.
Sintassi
- BigInteger variable_name = new BigInteger ("12345678901234567890"); // un intero decimale come stringa
- BigInteger variable_name = new BigInteger ("1010101101010100101010011000110011101011000111110000101011010010", 2) // un numero intero binario come stringa
- BigInteger variable_name = new BigInteger ("ab54a98ceb1f0800", 16) // un numero intero esadecimale come stringa
- BigInteger variable_name = new BigInteger (64, new Random ()); // un generatore di numeri pseudocasuali che fornisce 64 bit per costruire un numero intero
- BigInteger variable_name = new BigInteger (nuovo byte [] {0, -85, 84, -87, -116, -21, 31, 10, -46}); // ha firmato la rappresentazione a complemento di due di un intero (big endian)
- BigInteger variable_name = new BigInteger (1, new byte [] {- 85, 84, -87, -116, -21, 31, 10, -46}); // rappresentazione di complementi a due senza segno di un numero intero positivo (big endian)
Osservazioni
BigInteger
è immutabile. Quindi non puoi cambiare il suo stato. Ad esempio, quanto segue non funzionerà in quanto la sum
non verrà aggiornata a causa dell'immutabilità.
BigInteger sum = BigInteger.ZERO;
for(int i = 1; i < 5000; i++) {
sum.add(BigInteger.valueOf(i));
}
Assegna il risultato alla variabile sum
per farlo funzionare.
sum = sum.add(BigInteger.valueOf(i));
La documentazione ufficiale di BigInteger
afferma che BigInteger
implementazioni di BigInteger
dovrebbero supportare tutti i numeri interi compresi tra -2 2147483647 e 2 2147483647 (esclusivo). Ciò significa che BigInteger
può avere più di 2 miliardi di bit!
Inizializzazione
La classe java.math.BigInteger
fornisce operazioni analoghe a tutti gli operatori di numeri interi primitivi di Java e per tutti i metodi rilevanti da java.lang.Math
. Poiché il pacchetto java.math
non viene reso automaticamente disponibile, potrebbe essere necessario importare java.math.BigInteger
prima di poter utilizzare il nome semplice della classe.
Per convertire valori long
o int
in BigInteger
utilizzare:
long longValue = Long.MAX_VALUE;
BigInteger valueFromLong = BigInteger.valueOf(longValue);
o, per i numeri interi:
int intValue = Integer.MIN_VALUE; // negative
BigInteger valueFromInt = BigInteger.valueOf(intValue);
che si amplia intValue
intero a lungo, con segno estensione bit per i valori negativi, in modo che i valori negativi rimarranno negativo.
Per convertire una String
numerica in BigInteger
utilizzare:
String decimalString = "-1";
BigInteger valueFromDecimalString = new BigInteger(decimalString);
Il costruttore seguente viene utilizzato per tradurre la rappresentazione String di un BigInteger
nella radice specificata in un BigInteger
.
String binaryString = "10";
int binaryRadix = 2;
BigInteger valueFromBinaryString = new BigInteger(binaryString , binaryRadix);
Java supporta anche la conversione diretta di byte in un'istanza di BigInteger
. Attualmente è possibile utilizzare solo la codifica big endian con segno e senza segno:
byte[] bytes = new byte[] { (byte) 0x80 };
BigInteger valueFromBytes = new BigInteger(bytes);
Questo genererà un'istanza BigInteger
con valore -128 poiché il primo bit viene interpretato come il bit di segno.
byte[] unsignedBytes = new byte[] { (byte) 0x80 };
int sign = 1; // positive
BigInteger valueFromUnsignedBytes = new BigInteger(sign, unsignedBytes);
Ciò genererà un'istanza BigInteger
con il valore 128 poiché i byte vengono interpretati come numero senza segno e il segno è impostato esplicitamente su 1, un numero positivo.
Esistono costanti predefinite per valori comuni:
-
BigInteger.ZERO
- valore di "0". -
BigInteger.ONE
- valore di "1". -
BigInteger.TEN
- valore di "10".
C'è anche BigInteger.TWO
(valore di "2"), ma non puoi usarlo nel tuo codice perché è private
.
Confronto tra i BigInteger
Puoi confrontare BigIntegers
come se confrontassi String
o altri oggetti in Java.
Per esempio:
BigInteger one = BigInteger.valueOf(1);
BigInteger two = BigInteger.valueOf(2);
if(one.equals(two)){
System.out.println("Equal");
}
else{
System.out.println("Not Equal");
}
Produzione:
Not Equal
Nota:
In generale, non utilizzare l'operatore ==
per confrontare BigIntegers
-
==
operatore: confronta i riferimenti; vale a dire se due valori si riferiscono allo stesso oggetto - metodo
equals()
: confronta il contenuto di due BigIntegers.
Ad esempio, BigIntegers non dovrebbe essere confrontato nel modo seguente:
if (firstBigInteger == secondBigInteger) {
// Only checks for reference equality, not content equality!
}
Ciò potrebbe portare a comportamenti imprevisti, in quanto l'operatore ==
controlla solo l'uguaglianza di riferimento. Se entrambi i BigInteger contengono lo stesso contenuto, ma non si riferiscono allo stesso oggetto, ciò fallirà. Invece, confronta BigIntegers usando i metodi equals
, come spiegato sopra.
Puoi anche confrontare il tuo BigInteger
con valori costanti come 0,1,10.
per esempio:
BigInteger reallyBig = BigInteger.valueOf(1);
if(BigInteger.ONE.equals(reallyBig)){
//code when they are equal.
}
Puoi anche confrontare due BigInteger usando il metodo compareTo()
, come segue: compareTo()
restituisce 3 valori.
- 0: quando entrambi sono uguali .
- 1: Quando il primo è maggiore del secondo (quello tra parentesi).
- -1: quando il primo è meno del secondo
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.
}
Esempi di operazioni matematiche di BigInteger
BigInteger si trova in un oggetto immutabile, quindi è necessario assegnare i risultati di qualsiasi operazione matematica a una nuova istanza di BigInteger.
Aggiunta: 10 + 10 = 20
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("10");
BigInteger sum = value1.add(value2);
System.out.println(sum);
uscita: 20
Sottrazione: 10 - 9 = 1
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("9");
BigInteger sub = value1.subtract(value2);
System.out.println(sub);
uscita: 1
Divisione: 10/5 = 2
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("5");
BigInteger div = value1.divide(value2);
System.out.println(div);
uscita: 2
Divisione: 17/4 = 4
BigInteger value1 = new BigInteger("17");
BigInteger value2 = new BigInteger("4");
BigInteger div = value1.divide(value2);
System.out.println(div);
uscita: 4
Moltiplicazione: 10 * 5 = 50
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("5");
BigInteger mul = value1.multiply(value2);
System.out.println(mul);
uscita: 50
Potenza: 10 ^ 3 = 1000
BigInteger value1 = new BigInteger("10");
BigInteger power = value1.pow(3);
System.out.println(power);
uscita: 1000
Resto: 10% 6 = 4
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("6");
BigInteger power = value1.remainder(value2);
System.out.println(power);
uscita: 4
GCD: Greatest Common Divisor (GCD) per 12
e 18
è 6
.
BigInteger value1 = new BigInteger("12");
BigInteger value2 = new BigInteger("18");
System.out.println(value1.gcd(value2));
Uscita: 6
Massimo di due BigInteger:
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("11");
System.out.println(value1.max(value2));
Uscita: 11
Minimo di due BigInteger:
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("11");
System.out.println(value1.min(value2));
Uscita: 10
Operazioni di logica binaria su BigInteger
BigInteger supporta anche le operazioni di logica binaria disponibili per i tipi Number
. Come con tutte le operazioni, vengono implementate chiamando un metodo.
Binario o:
BigInteger val1 = new BigInteger("10");
BigInteger val2 = new BigInteger("9");
val1.or(val2);
Uscita: 11 (che equivale a
10 | 9
)
Binario E:
BigInteger val1 = new BigInteger("10");
BigInteger val2 = new BigInteger("9");
val1.and(val2);
Uscita: 8 (che equivale a
10 & 9
)
Binario Xor:
BigInteger val1 = new BigInteger("10");
BigInteger val2 = new BigInteger("9");
val1.xor(val2);
Uscita: 3 (che equivale a
10 ^ 9
)
RightShift:
BigInteger val1 = new BigInteger("10");
val1.shiftRight(1); // the argument be an Integer
Uscita: 5 (equivalente a
10 >> 1
)
Tasto maiuscolo di sinistra:
BigInteger val1 = new BigInteger("10");
val1.shiftLeft(1); // here parameter should be Integer
Uscita: 20 (equivalente a
10 << 1
)
Inversione binaria (non):
BigInteger val1 = new BigInteger("10");
val1.not();
Uscita: 5
NAND (And-Not): *
BigInteger val1 = new BigInteger("10");
BigInteger val2 = new BigInteger("9");
val1.andNot(val2);
Uscita: 7
Generazione di BigInteger casuali
La classe BigInteger
ha un costruttore dedicato alla generazione di BigIntegers
casuali, data un'istanza di java.util.Random
e un int
che specifica quanti bit avrà il BigInteger
. Il suo utilizzo è abbastanza semplice: quando chiamate il costruttore BigInteger(int, Random)
questo modo:
BigInteger randomBigInt = new BigInteger(bitCount, sourceOfRandomness);
quindi finirai con un BigInteger
cui valore è compreso tra 0 (incluso) e 2 bitCount
(esclusivo).
Ciò significa anche che il new BigInteger(2147483647, sourceOfRandomness)
può restituire tutti i BigInteger
positivi con un tempo sufficiente.
Che cosa sarà sourceOfRandomness
dipende da te. Ad esempio, un new Random()
è abbastanza buono nella maggior parte dei casi:
new BigInteger(32, new Random());
Se sei disposto a rinunciare alla velocità per numeri casuali di alta qualità, puoi invece utilizzare un new SecureRandom ()
:
import java.security.SecureRandom;
// somewhere in the code...
new BigInteger(32, new SecureRandom());
Puoi addirittura implementare un algoritmo al volo con una classe anonima! Nota che il lancio del tuo algoritmo RNG ti farà finire con una casualità di bassa qualità , quindi assicurati sempre di usare un algoritmo che sia risultato accettabile a meno che tu non voglia che i BigInteger
risultanti siano prevedibili.
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;
}
});