boolean
i char
, są one podzielone na następujące typy:
- liczby całkowite:
byte
,short
,int
ilong
; - zmiennoprzecinkowe (zwane także liczbami rzeczywistymi):
float
idouble
.
long
, z zakresem od -9223372036854775808 do 9223372036854775807. Z liczb zmiennoprzecinkowych, double
z 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ć BigInteger
i BigDecimal
.
BigInteger w Javie
Klasa JavaBigInteger
jest 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 - , , Integer
itd Long
. - dlatego posiada implementacje metod prowadzących do typów prostych: Byte
Double
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 BigInteger
z 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 BigInteger
posiadające odpowiednio wartości 0
, 1
i 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
-
operacje z obliczaniem modów :
BigInteger firstValue = new BigInteger("-34"); BigInteger secondValue = new BigInteger("5"); BigInteger resultValue = firstValue.mod(secondValue); //1
-
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
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 BigInteger
jest BigDecimal
potomkiem klasy Number
i 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 konstruktoromBigDecimal
, 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
, String
a 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
KlasaBigDecimal
zawiera również metody do różnych operacji arytmetycznych, ale BigInteger
nie posiada metod pracy z bitami, takich jak . Niemniej jednak główną cechą BigDecimal
jest 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ć
BigDecimal
przez innyBigDecimal
, 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ątrzBigDecimal
moż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 BigDecimal
stałe podobne do stałych BigInteger ZERO
i . 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. ONE
TEN
BigInteger
BigDecimal
immutable
String
GO TO FULL VERSION