JavaRush /Blog Java /Random-PL /BigInteger i BigDecimal

BigInteger i BigDecimal

Opublikowano w grupie Random-PL
W Javie aplikacja składa się z klas, a klasy z metod i zmiennych. Zmienne z kolei dzielą się na pierwotne i referencyjne. BigInteger i BigDecimal — 1W Javie istnieje 8 typów zmiennych i, za wyjątkiem booleani char, są one podzielone na następujące typy:
  • liczby całkowite: byte, short, inti long;
  • zmiennoprzecinkowe (zwane także liczbami rzeczywistymi): floati double.
W obrębie tych małych grup różnice istnieją jedynie w zakresie wartości, które można uwzględnić (i odpowiednio zajmowana przestrzeń takiej zmiennej jest różna). Największym typem liczb całkowitych jest long, z zakresem od -9223372036854775808 do 9223372036854775807. Z liczb zmiennoprzecinkowych, doublez zakresem od 1,7e-308 do 1,7e+308. Więcej o liczbach rzeczywistych możesz przeczytać w tym artykule . Ale co, jeśli będziemy musieli przechowywać liczby przekraczające dopuszczalny zakres? W tym przypadku będziemy potrzebować BigIntegeri BigDecimal.

BigInteger w Javie

Klasa Java BigIntegerjest używana jako analogia do wartości całkowitych o dowolnej długości, które nie mają 64-bitowego limitu długości. Co więcej, jest potomkiem klasy Number, podobnie jak standardowe opakowania dla numerycznych typów prostych - , , Integeritd Long. - dlatego posiada implementacje metod prowadzących do typów prostych: ByteDouble
BigInteger value = new BigInteger("32145");

int intValue = value.intValue();//32145

long longValue = value.longValue();//32145

double doubleValue = value.doubleValue();//32145.0
Natychmiast widzimy utworzenie takiego obiektu BigIntegerz przekazaniem naszej wartości do konstruktora, ale w formacie string. Warto dodać, że ma niejednego projektanta, ale na każdą okazję. Jeśli typy pierwotne nie pomieszczą pełnej ilości danych z BigInteger, dane zostaną obcięte do zakresu tego typu pierwotnego. Ale jednocześnie istnieją analogie tych metod ( intValueExact()itd longValueExact().), z tą tylko różnicą, że jeśli prosty typ, na który odbywa się konwersja, nie mieści się w zakresie danych, zgłaszany jest wyjątek ArithmeticException .

Stałe BigInteger

Do użytku wewnętrznego klasa ma stałe:
BigInteger.ZERO
BigInteger.ONE
BigInteger.TEN
Są to obiekty stałe BigIntegerposiadające odpowiednio wartości 0, 1i 10.

Metody BigInteger

Jedną z głównych cech tej klasy jest to, że jest pełna metod implementujących standardowe operacje arytmetyczne w Javie. Na przykład:
  • operacje sumowania:

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.add(secondValue);//73461
  • operacje mnożenia:

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.multiply(secondValue);//1347530670
  • operacje znajdowania reszty z dzielenia jednej liczby przez drugą:

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.remainder(secondValue);//2529
  • uzyskanie wartości bezwzględnej liczby (czyli modulo, bez znaku):

    BigInteger firstValue = new BigInteger("-37995");
    BigInteger resultValue =  firstValue.abs();//37995
Istnieją również metody dla bardziej złożonych (specyficznych) operacji:
  • operacje z obliczaniem modów :

    BigInteger firstValue = new BigInteger("-34");
    BigInteger secondValue = new BigInteger("5");
    BigInteger resultValue = firstValue.mod(secondValue); //1
Istnieje kilka różnych odmian tej funkcji:
  • uzyskanie losowej liczby i określenie liczby bitów, których użyje wynikowa wartość:

    BigInteger firstValue = BigInteger.probablePrime(8, new Random());//211
    BigInteger secondValue = BigInteger.probablePrime(16, new Random());//42571
  • operacje przesunięcia bitowego (this >> n)

    Przesuń w lewo:

    BigInteger firstValue = new BigInteger("5");
    BigInteger firstResultValue = firstValue.shiftLeft(3);//40

    Przesuń w prawo:

    BigInteger secondValue = new BigInteger("34");
    BigInteger secondResultValue = secondValue.shiftRight(2); //8
Oczywiście lepiej przyjrzeć się pełnej liście metod w dokumentacji . BigInteger i BigDecimal — 2

BigDecimal w Javie

Gdy potrzebujemy liczby rzeczywistej o dowolnej długości, używana jest klasa Java - BigDecimal. Z reguły służy do pracy z finansami zamiast double, ponieważ daje więcej opcji dostosowywania. Like i BigIntegerjest BigDecimalpotomkiem klasy Numberi posiada metody zwracające wartość obiektu jako określony typ pierwotny:
BigDecimal value = new BigDecimal(35563.3);

long longValue = value.longValue();//35563

double doubleValue = value.doubleValue();//35563.3
Jak widzimy podczas redukcji do long, pozostaje tylko część całkowita, a miejsca dziesiętne są odrzucane.

Konstruktory BigDecimal

Przyjrzymy się bliżej konstruktorom BigDecimal, gdyż klasa ma ich znacznie większy wybór. Istnieją konstruktory, które pozwalają ustawić wartość obiektu na różne sposoby (poprzez przekazanie int, long, double, Stringa nawet BigInteger), i są takie, które na to pozwalają. ustaw ustawienia tworzonego obiektu (metody zaokrąglania, liczba miejsc po przecinku):
BigDecimal firstValue = new BigDecimal("455656.545");//455656.545
Tutaj wszystko jest jasne, bezpośrednio ustawiamy wartość i liczbę miejsc po przecinku, które chcemy zobaczyć.
BigDecimal secondValue = new BigDecimal(3445.54);//3445.5399999999999636202119290828704833984375
Wyniki tego konstruktora mogą być dość nieprzewidywalne, ponieważ określamy typ double, który ze swej natury jest typem bardzo niejednoznacznym. Dlatego ogólnie zaleca się użycie w konstruktorze String.
BigDecimal thirdValue = new BigDecimal(3445.554645675444, MathContext.DECIMAL32);//3445.555
Ustawiamy double, ale jednocześnie ustawiamy również parametr opisujący regułę zaokrąglania (który zawiera liczbę miejsc po przecinku i algorytm zaokrąglania).
char[] arr = new String("455656.545").toCharArray();

BigDecimal fourthValue = new BigDecimal(arr, 2, 6);//5656.5
Ustawiamy tablicę znaków, z którego elementu pobieramy wartości dla obiektu i ile tych elementów pobieramy.
BigDecimal fifthValue = new BigDecimal(new BigInteger("44554"), 3);//44.554
Bierzemy już istniejący obiekt BigInteger, ustalamy liczbę miejsc po przecinku.

Metody BigDecimal

Klasa BigDecimalzawiera również metody do różnych operacji arytmetycznych, ale BigIntegernie posiada metod pracy z bitami, takich jak . Niemniej jednak główną cechą BigDecimaljest elastyczność pracy z liczbami zmiennoprzecinkowymi. Przyjrzyjmy się kilku technikom, które pozwalają nam opanować liczby rzeczywiste:
  • otrzymujemy precyzję (liczbę liczb):

    BigDecimal value = new BigDecimal("454334.34334");
    int result = value.precision();//11
  • ustaw liczbę miejsc po przecinku i zasadę zaokrąglania:

    BigDecimal firstValue = new BigDecimal(3445.544445);
    
    BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_CEILING);//3445.545

    Poniżej przyjrzymy się bliżej stałym służącym do ustalania reguł zaokrąglania.

  • podzielić BigDecimalprzez inny BigDecimal, wskazując wymaganą liczbę miejsc po przecinku i zasadę zaokrąglania:

    BigDecimal firstValue = new BigDecimal("455656.545");
    
    BigDecimal secondValue = new BigDecimal(3445.544445);
    
    BigDecimal result = firstValue.divide(secondValue, 2,RoundingMode.DOWN);//132.24
  • przesuwanie przecinka w prawo/w lewo o określoną liczbę miejsc:

    BigDecimal value = new BigDecimal("455656.545");
    BigDecimal firstResult = value.movePointRight (2);//45565654.5
    BigDecimal secondResult = value.movePointLeft (2);//4556.56545
  • przytnij zera końcowe:

    BigDecimal value = new BigDecimal("45056.5000");
    BigDecimal result = value.stripTrailingZeros();//45056.5

    Jeżeli w części rzeczywistej mamy same zera i w części całkowitej są też zera (albo w ogóle nie mamy miejsc po przecinku), to:

    BigDecimal value = new BigDecimal("450000.000");
    BigDecimal result = value.stripTrailingZeros();//4.5E+5

Reguły zaokrąglania BigDecimal

Aby ustawić reguły zaokrąglania, wewnątrz BigDecimalmożemy zobaczyć specjalne stałe opisujące algorytmy zaokrąglania: ROUND_UP- zaokrąglanie od zera, zaokrąglanie w stronę części rzeczywistej:
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— zaokrąglenie do zera, czyli obcięcie części rzeczywistej:
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— zaokrąglenie do dodatniej nieskończoności. Oznacza to, że jeśli nasza liczba jest dodatnia, to -> ROUND_UP, jeśli ujemna, to ->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- zaokrąglenie do ujemnej nieskończoności, czyli jeżeli nasza liczba jest dodatnia to -> ROUND_DOWN, jeśli ujemna to ->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
Dla rozważanej wartości tę najbliższą liczbę z obciętym miejscem po przecinku uznamy za najbliższego sąsiada rozważanej liczby. Na przykład 2,43 będzie bliższe 2,4 niż 2,5, ale 2,48 będzie bliższe 2,5. ROUND_HALF_DOWN— zaokrąglenie do „najbliższego sąsiada”. Jeżeli obaj sąsiedzi są w jednakowej odległości od określonej wartości, wówczas przeprowadzane jest zaokrąglanie do zera. Równoodległość ma miejsce na przykład wtedy, gdy zaokrąglana liczba wynosi 5 i jest to ta sama odległość od 0 i 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— tryb zaokrąglania w kierunku „najbliższego sąsiada”. Jeśli obaj sąsiedzi są w równej odległości, wykonywane jest zaokrąglanie (jest to to samo zaokrąglanie, którego uczono nas w szkole):
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— zaokrąglenie do „najbliższego sąsiada”, jeżeli obaj sąsiedzi nie są w jednakowej odległości. W takim przypadku, jeżeli zaokrąglana liczba jest poprzedzona liczbą nieparzystą, to jest ona zaokrąglana w górę, a jeśli jest parzysta, to jest zaokrąglana w dół:
BigDecimal firstValue = new BigDecimal("2222.2225");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.222
Otrzymujemy ten wynik, ponieważ podczas zaokrąglania 5 patrzy na poprzednią liczbę 2 i widząc, że jest parzysta, zaokrągla w dół. Ale jeśli:
BigDecimal firstValue = new BigDecimal("2222.22255");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.223
Zaokrąglanie wzrasta, ponieważ ostatnie 5 sprawdza poprzednią wartość i widzi liczbę nieparzystą. W rezultacie liczba jest zaokrąglana w górę do 6, po czym zaokrąglana jest również następna 6. Ale szóstka nie patrzy już na liczbę po lewej stronie, ponieważ liczba jest wyraźnie bliżej góry, w wyniku czego ostatnie 2 są zwiększane o 1. ROUND_UNNECESSARY- służy do sprawdzania, czy liczby nie trzeba zaokrąglać. Oznacza to, że sprawdzamy, czy liczba ma wymaganą liczbę miejsc po przecinku:
BigDecimal firstValue = new BigDecimal("2.55");
BigDecimal firstResult =  firstValue.setScale(2, BigDecimal.ROUND_UNNECESSARY);//2.55
Tutaj wszystko jest w porządku, wartość ma dwie cyfry i sprawdzamy, czy po przecinku są tylko dwie cyfry. Ale jeśli:
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_UNNECESSARY);
Następnie otrzymujemy - ArithmeticException, ponieważ testowana wartość przekracza określoną liczbę miejsc po przecinku. Ale jeśli sprawdzimy dwa miejsca po przecinku, ale tak naprawdę jest tam jedno, to wyjątek nie zostanie zgłoszony, a brakujące cyfry zostaną po prostu uzupełnione zerami:
BigDecimal thirdValue = new BigDecimal("2.5");
BigDecimal thirdResult = thirdValue.setScale(3, BigDecimal.ROUND_UNNECESSARY   );//2.500
Chciałbym również zauważyć, że y ma BigDecimalstałe podobne do stałych BigInteger ZEROi . Oto link do dokumentacji . I na koniec: jak zapewne zauważyłeś, wykonując operacje na obiektach i , nie zmieniamy starych, ale zawsze dostajemy nowe. To mówi nam, że są one , czyli niezmienne po ich stworzeniu, tak jak . Innymi słowy, wszystkie ich metody nie mogą zmienić stanu wewnętrznego obiektu, co najwyżej mogą zwrócić nowy obiekt o parametrach określonych przez funkcję, której używamy. ONETENBigIntegerBigDecimalimmutableString
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION