Szukaj…


Wprowadzenie

Klasa BigInteger jest używana do operacji matematycznych z udziałem dużych liczb całkowitych o wielkościach zbyt dużych dla prymitywnych typów danych. Na przykład 100-silnia to 158 cyfr - znacznie większa niż long może reprezentować. BigInteger zapewnia analogie do wszystkich pierwotnych operatorów liczb całkowitych Javy oraz wszystkich odpowiednich metod z java.lang.Math a także kilku innych operacji.

Składnia

  • BigInteger nazwa_zmiennej = nowy BigInteger („12345678901234567890”); // liczba dziesiętna jako ciąg
  • BigInteger nazwa_zmiennej = nowy BigInteger („1010101101010100101010011000110011101011000111110000101011010010”, 2) // binarna liczba całkowita jako ciąg
  • BigInteger nazwa_zmiennej = nowy BigInteger ("ab54a98ceb1f0800", 16) // liczba szesnastkowa jako ciąg
  • BigInteger nazwa_zmiennej = nowy BigInteger (64, nowy Random ()); // generator liczb pseudolosowych dostarczający 64 bity do skonstruowania liczby całkowitej
  • BigInteger nazwa_zmiennej = nowy BigInteger (nowy bajt [] {0, -85, 84, -87, -116, -21, 31, 10, -46}); // podpisano reprezentację uzupełnienia dwóch liczb całkowitych (big endian)
  • BigInteger nazwa_zmiennej = nowy BigInteger (1, nowy bajt [] {- 85, 84, -87, -116, -21, 31, 10, -46}); // reprezentacja dopełniacza dwóch niepodpisanych liczb całkowitych dodatnich (big endian)

Uwagi

BigInteger jest niezmienny. Dlatego nie możesz zmienić jego stanu. Na przykład poniższe nie będą działać, ponieważ sum nie zostanie zaktualizowana z powodu niezmienności.

BigInteger sum = BigInteger.ZERO;
for(int i = 1; i < 5000; i++) {
   sum.add(BigInteger.valueOf(i));  
}

Przypisz wynik do zmiennej sum aby działała.

sum = sum.add(BigInteger.valueOf(i));

Java SE 8

Oficjalna dokumentacja BigInteger stwierdza, że implementacje BigInteger powinny obsługiwać wszystkie liczby całkowite od -2 2147483647 do 2 2147483647 (wyłącznie). Oznacza to, że BigInteger może mieć ponad 2 miliardy bitów!

Inicjalizacja

Klasa java.math.BigInteger zapewnia operacje analogiczne do wszystkich prymitywnych operatorów liczb całkowitych Javy oraz dla wszystkich odpowiednich metod z java.lang.Math . Ponieważ pakiet java.math nie jest automatycznie udostępniany, może być konieczne zaimportowanie java.math.BigInteger zanim będzie można użyć prostej nazwy klasy.

Aby przekonwertować long lub int wartości BigInteger użytku:

long longValue = Long.MAX_VALUE;
BigInteger valueFromLong = BigInteger.valueOf(longValue); 

lub, w przypadku liczb całkowitych:

int intValue = Integer.MIN_VALUE; // negative
BigInteger valueFromInt = BigInteger.valueOf(intValue);

który rozszerzy liczbę całkowitą intValue na długi, używając rozszerzenia bitu intValue dla wartości ujemnych, dzięki czemu wartości ujemne pozostaną ujemne.


Aby przekonwertować String liczbowy na BigInteger użyj:

String decimalString = "-1";
BigInteger valueFromDecimalString = new BigInteger(decimalString);

Poniższy konstruktor służy do przetłumaczenia reprezentacji łańcuchowej BigInteger w podanej BigInteger na BigInteger .

String binaryString = "10";
int binaryRadix = 2;
BigInteger valueFromBinaryString = new BigInteger(binaryString , binaryRadix);

Java obsługuje także bezpośrednią konwersję bajtów na instancję BigInteger . Obecnie można używać tylko podpisanego i niepodpisanego kodowania Big Endian:

byte[] bytes = new byte[] { (byte) 0x80 }; 
BigInteger valueFromBytes = new BigInteger(bytes);

To wygeneruje instancję BigInteger o wartości -128, ponieważ pierwszy bit jest interpretowany jako bit znaku.

byte[] unsignedBytes = new byte[] { (byte) 0x80 };
int sign = 1; // positive
BigInteger valueFromUnsignedBytes = new BigInteger(sign, unsignedBytes);

To wygeneruje instancję BigInteger o wartości 128, ponieważ bajty są interpretowane jako liczba bez znaku, a znak jest jawnie ustawiony na 1, liczbę dodatnią.


Istnieją predefiniowane stałe wspólnych wartości:

  • BigInteger.ZERO - wartość „0”.
  • BigInteger.ONE - wartość „1”.
  • BigInteger.TEN - wartość „10”.

Istnieje również BigInteger.TWO (wartość „2”), ale nie można go użyć w kodzie, ponieważ jest private .

Porównywanie BigIntegers

Możesz porównać BigIntegers tak samo jak porównujesz String lub inne obiekty w Javie.

Na przykład:

BigInteger one = BigInteger.valueOf(1);
BigInteger two = BigInteger.valueOf(2);

if(one.equals(two)){
    System.out.println("Equal");
}
else{
    System.out.println("Not Equal");
}

Wynik:

Not Equal

Uwaga:

Zasadniczo nie używaj operatora == do porównywania BigIntegers

  • == operator: porównuje referencje; tzn. czy dwie wartości odnoszą się do tego samego obiektu
  • Metoda equals() : porównuje zawartość dwóch BigIntegers.

Na przykład BigIntegers nie należy porównywać w następujący sposób:

if (firstBigInteger == secondBigInteger) {
  // Only checks for reference equality, not content equality!
}

Może to spowodować nieoczekiwane zachowanie, ponieważ operator == sprawdza tylko równość odniesienia. Jeśli oba BigInteger zawierają tę samą treść, ale nie odnoszą się do tego samego obiektu, to się nie powiedzie. Zamiast tego porównaj BigIntegers, stosując metody equals , jak wyjaśniono powyżej.

Możesz także porównać BigInteger ze stałymi wartościami, takimi jak 0,1,10.

na przykład:

BigInteger reallyBig = BigInteger.valueOf(1);
if(BigInteger.ONE.equals(reallyBig)){
    //code when they are equal.
}    

Możesz także porównać dwie BigIntegery za pomocą metody CompareTo compareTo() , ponieważ: compareTo() zwraca 3 wartości.

  • 0: Gdy oba są równe .
  • 1: Gdy pierwszy jest większy niż drugi (ten w nawiasach).
  • -1: Gdy pierwszy jest krótszy niż drugi.
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.
}

Przykłady operacji matematycznych BigInteger

BigInteger znajduje się w niezmiennym obiekcie, więc musisz przypisać wyniki dowolnej operacji matematycznej do nowej instancji BigInteger.

Dodanie: 10 + 10 = 20

BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("10");

BigInteger sum = value1.add(value2);
System.out.println(sum);

wyjście: 20

Odejmowanie: 10 - 9 = 1

BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("9");

BigInteger sub = value1.subtract(value2);
System.out.println(sub);

wyjście: 1

Podział: 10/5 = 2

BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("5");

BigInteger div = value1.divide(value2);
System.out.println(div);

wyjście: 2

Podział: 17/4 = 4

BigInteger value1 = new BigInteger("17");
BigInteger value2 = new BigInteger("4");

BigInteger div = value1.divide(value2);
System.out.println(div);

wyjście: 4

Mnożenie: 10 * 5 = 50

BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("5");

BigInteger mul = value1.multiply(value2);
System.out.println(mul);

wyjście: 50

Moc: 10 ^ 3 = 1000

BigInteger value1 = new BigInteger("10");
BigInteger power = value1.pow(3);
System.out.println(power);

wyjście: 1000

Reszta: 10% 6 = 4

BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("6");

BigInteger power = value1.remainder(value2);
System.out.println(power);

wyjście: 4

GCD: Greatest Common Divisor (GCD) dla 12 i 18 to 6 .

BigInteger value1 = new BigInteger("12");
BigInteger value2 = new BigInteger("18");

System.out.println(value1.gcd(value2));

Wyjście: 6

Maksymalnie dwa BigIntegers:

BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("11");

System.out.println(value1.max(value2));

Wyjście: 11

Co najmniej dwie duże liczby całkowite:

BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("11");

System.out.println(value1.min(value2));

Wyjście: 10

Operacje binarne na BigInteger

BigInteger obsługuje również operacje logiki binarnej, które są również dostępne dla typów Number . Podobnie jak w przypadku wszystkich operacji, są one realizowane przez wywołanie metody.

Binarny lub:

BigInteger val1 = new BigInteger("10");
BigInteger val2 = new BigInteger("9");

val1.or(val2);

Wyjście: 11 (co odpowiada 10 | 9 )

Binarny i:

BigInteger val1 = new BigInteger("10");
BigInteger val2 = new BigInteger("9");

val1.and(val2);

Wyjście: 8 (co odpowiada 10 & 9 )

Binarny Xor:

BigInteger val1 = new BigInteger("10");
BigInteger val2 = new BigInteger("9");

val1.xor(val2);

Wyjście: 3 (co odpowiada 10 ^ 9 )

RightShift:

BigInteger val1 = new BigInteger("10");

val1.shiftRight(1);   // the argument be an Integer    

Wyjście: 5 (odpowiednik 10 >> 1 )

Lewy Shift:

BigInteger val1 = new BigInteger("10");

val1.shiftLeft(1);   // here parameter should be Integer    

Wyjście: 20 (odpowiednik 10 << 1 )

Inwersja binarna (nie):

BigInteger val1 = new BigInteger("10");

val1.not();

Wyjście: 5

NAND (i nie): *

BigInteger val1 = new BigInteger("10");
BigInteger val2 = new BigInteger("9");

val1.andNot(val2);

Wyjście: 7

Generowanie losowych BigIntegers

Klasa BigInteger ma konstruktor dedykowany do generowania losowych BigIntegers , biorąc pod uwagę instancję java.util.Random oraz int która określa, ile bitów będzie miała BigInteger . Jego użycie jest dość proste - gdy wywołujesz konstruktor BigInteger(int, Random) następujący sposób:

BigInteger randomBigInt = new BigInteger(bitCount, sourceOfRandomness);

skończysz z BigInteger którego wartość wynosi od 0 (włącznie) do 2 bitCount (wyłącznie).

Oznacza to również, że new BigInteger(2147483647, sourceOfRandomness) może zwrócić wszystkie pozytywne wartości BigInteger mając wystarczająco dużo czasu.


To, co będzie sourceOfRandomness zależy od Ciebie. Na przykład new Random() jest wystarczająca w większości przypadków:

new BigInteger(32, new Random());

Jeśli chcesz zrezygnować z szybkości dla liczb losowych o wyższej jakości, możesz zamiast tego użyć new SecureRandom () :

import java.security.SecureRandom;

// somewhere in the code...
new BigInteger(32, new SecureRandom());

Możesz nawet zaimplementować algorytm w locie z anonimową klasą! Pamiętaj, że wprowadzenie własnego algorytmu RNG spowoduje losowość niskiej jakości , więc zawsze upewnij się, że używasz algorytmu, który okazał się przyzwoity, chyba że chcesz, aby wynikowe wartości BigInteger były przewidywalne.

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;
    }
});


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow