Примитивен тип | Размер в паметта | Диапазон на стойността |
---|---|---|
byte | 8 бита | -128 до 127 |
къс | 16 бита | -32768 до 32767 |
въглен | 16 бита | 0 до 65536 |
вътр | 32 бита | -2147483648 до 2147483647 |
дълго | 64 бита | -9223372036854775808 до 9223372036854775807 |
плавам | 32 бита | (2 на степен -149) до ((2 на степен -23) * 2 на степен 127) |
двойно | 64 бита | (-2 на степен 63) до ((2 на степен 63) - 1) |
булево | 8 (когато се използва в масиви), 32 (когато не се използва в масиви) | истина or лъжа |
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigDecimal decimal = new BigDecimal("123.444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444");
System.out.println(decimal);
}
}
Предаването на низ към конструктора е само една възможна опция. Тук използваме низове, защото нашите числа надвишават максималните стойности за long и double и се нуждаем от няHowъв начин да обясним на компилатора кое число искаме да създадем :) Просто предаване на числото 1111111111111111111111111111111111111111111111111111111111111111111111 към конструктора няма да работи: Java ще се опита да натъпче подаденото число в един от примитивните типове данни, но то няма да се побере в нито един от тях. Ето защо използването на низ за предаване на желаното число е добър вариант. И двата класа могат автоматично да извличат числови стойности от предадените низове. Друг важен момент, който трябва да запомните, когато работите с класове с големи числа, е, че техните обекти са неизменни ( Immutable ). Вече сте запознати с неизменността благодарение на опита си с класа String и класовете обвивки за примитивни типове (Integer, Long и т.н.).
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
integer.add(BigInteger.valueOf(33333333));
System.out.println(integer);
}
}
Конзолен изход:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Както бихте очаквали, нашият номер не се е променил. За да извършите операцията по добавяне, трябва да създадете нов обект, за да получите резултата от операцията.
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigInteger result = integer.add(BigInteger.valueOf(33333333));
System.out.println(result);
}
}
Конзолен изход:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
Вижте, сега всичко работи Howто трябва :) Между другото, забелязахте ли колко необичайно изглежда операцията за добавяне?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
Това е друг важен момент. Класовете с големи числа не използват операторите + - * /. Вместо това те предоставят набор от методи. Нека се запознаем с основните (Howто винаги, можете да намерите пълен списък с методи в documentацията на Oracle: тук и тук ).
-
методи за аритметични операции: add() , subtract() , multiply() , divide() . Тези методи се използват съответно за събиране, изваждане, умножение и деление.
-
doubleValue() , intValue() , floatValue() , longValue() и т.н. се използват за преобразуване на голямо число в един от примитивните типове на Java. Бъдете внимателни, когато използвате тези методи. Не забравяйте за разликите в размера на битовете!
import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); long result = integer.longValue(); System.out.println(result); } }
Конзолен изход:
8198552921648689607
-
min() и max() ви позволяват да намерите минималната и максималната стойност на две големи числа.
Имайте предвид, че тези методи не са статични!import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); BigInteger integer2 = new BigInteger("222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"); System.out.println(integer.max(integer2)); } }
Конзолен изход:
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
BigDecimal поведение при закръгляване
Тази тема има отделен раздел, тъй като закръгляването на големи числа и конфигурирането на поведение при закръгляване не са толкова прости. Можете да използвате метода setScale() , за да зададете броя на десетичните знаци за BigDecimal . Да предположим например, че искаме числото 111.5555555555 да има три цифри след десетичната запетая. Не можем обаче да постигнем това, което искаме, като подадем числото 3 като аргумент на метода setScale() . Както бе споменато по-горе, BigDecimalе за представяне на числа със строги изисквания за изчислителна точност. В сегашния си вид нашето число има 10 цифри след десетичната запетая. Искаме да изпуснем 7 от тях и да запазим само 3. Съответно, освен числото 3, трябва да преминем и режима на закръгляване. BigDecimal има общо 8 режима на закръгляване. Това е много! Но ако наистина трябва да прецизирате прецизността на изчисленията си, ще имате всичко необходимо. И така, ето 8-те режима на закръгляване, предлагани от BigDecimal :-
ROUND_CEILING — закръглява нагоре
111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
-
ROUND_DOWN — закръгля към нула
111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
-
ROUND_FLOOR — закръглява надолу
111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555
-
ROUND_HALF_UP — закръглява нагоре, ако числото след десетичната запетая >= 0,5
0.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN — закръглява нагоре, ако числото след десетичната запетая > 0,5
0.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5 0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
-
ROUND_HALF_EVEN — закръгляването зависи от числото вляво от десетичната запетая. Ако числото отляво е четно, закръгляването ще бъде надолу. Ако числото вляво от десетичната запетая е нечетно, тогава закръгляването ще бъде нагоре.
2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2
Числото отляво на десетичната запетая е 2 (четно). Числото се закръгля надолу. Искаме 0 знака след десетичната запетая, така че резултатът е 2.
3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4
Числото вляво от десетичната запетая е 3 (нечетно). Числото се закръгля нагоре. Искаме 0 знака след десетичната запетая, така че резултатът е 4.
-
ROUND_UNNECCESSARY — Този режим се използва, когато трябва да подадете режим на закръгляване към метод, но числото не трябва да бъде закръглено. Ако се опитате да закръглите число със зададен режим ROUND_UNNECCESSARY, се хвърля ArithmeticException.
3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP — закръглява от нулата.
111.5551 -> setScale(3, ROUND_UP) -> 111.556
Сравняване на големи числа
Това също е важно. Спомняте си, че използваме метода equals() за сравняване на обекти в Java. Имплементацията се предоставя or от самия език (за стандартни Java класове), or се отменя от програмиста. Но в случай на BigDecimal обекти, използването на метода equals() за сравнения не се препоръчва. Това е така, защото методът BigDecimal.equals() връща true само ако 2-те числа имат една и съща стойност и мащаб: Нека сравним поведението на метода equals() за класовете Double и BigDecimal :
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
Double a = 1.5;
Double b = 1.50;
System.out.println(a.equals(b));
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.equals(y));
}
}
Конзолен изход:
true
false
Както можете да видите, за BigDecimal числата 1,5 и 1,50 се оказаха неравни! Това се дължи именно на спецификата на имплементацията на метода equals() в класа BigDecimal . За по-точно сравнение на два BigDecimal обекта е по-добре да използвате метода compareTo() :
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.compareTo(y));
}
}
Конзолен изход:
0
Методът compareTo() върна 0, което означава, че 1,5 и 1,50 са равни. И това е резултатът, който очаквахме! :) Това приключва днешния ни урок. Сега е време да се върнем към задачите! :)
GO TO FULL VERSION