| Примітивний тип | Розмір у пам'яті | Діапазон значень |
|---|---|---|
| byte | 8 біт | від -128 до 127 |
| short | 16 біт | до -32768 до 32767 |
| char | 16 біт | від 0 до 65536 |
| int | 32 біта | від -2147483648 до 2147483647 |
| long | 64 біта | від -9223372036854775808 до 9223372036854775807 |
| float | 32 біта | від (2 у ступені -149) до ((2-2 у ступені -23)*2 у ступені 127) |
| double | 64 біта | від (-2 у ступені 63) до ((2 у ступені 63) - 1) |
| boolean | 8 (при використанні в масивах), 32 (при використанні не в масивах) | true або false |
BigIntegerпрактично BigDecimalнічим не обмежений. Навіщо використовуються ці класи? Насамперед для обчислень з вкрай високими вимогами до точності. Є, наприклад, програми, у яких від точності обчислень може залежати людське життя (ПЗ для літаків і ракет або медичного устаткування). Тому якщо навіть 150-й розряд після коми відіграє важливу роль,BigDecimal- кращий вибір. Крім того, досить часто ці об'єкти застосовуються у світі фінансів, де точність обчислень аж до найменших значень теж є вкрай важливою. Як працювати з об'єктами BigIntegerта BigDecimalщо важливо про них пам'ятати? Об'єкти цих класів створюються так:
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, а якось треба пояснити компілятору, яке саме число ми хочемо отримати :) Просто передати в конструктор число 111111111111111111111111111111111111111111111111111111111111111111111111111111111 не вийде: 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);
}
}Виведення в консоль:
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 Наше число не змінилося, як і слід очікувати. Щоб операція додавання пройшла успішно, необхідно створити новий об'єкт і присвоїти йому результат додавання.
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);
}
}Виведення в консоль:
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444 Ось тепер все працює як треба :) До речі, звернув увагу, як незвичайно виглядає операція складання?
BigInteger result = integer.add(BigInteger.valueOf(33333333)); Це ще один важливий момент. Класи великих чисел не використовують у своїй роботі оператори +-*/, а надають натомість набір методів. Давай ознайомимося з основними (повний перелік методів ти, як і завжди, можеш знайти в документації 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
Ця тема винесена в окремий розділ, оскільки округлення великих чисел та його налаштування — річ не така проста. Ти можеш встановити кількість цифр після коми для числаBigDecimalза допомогою методу setScale(). Наприклад, ми хочемо встановити для числа 111.5555555555 точність три цифри після коми. Однак ми не зможемо передати число 3 як аргумент у метод setScale()і таким чином вирішити наше завдання. Як було сказано вище, BigDecimalце числа для обчислень з підвищеною точністю. У поточному вигляді наше число має 10 цифр після коми. Ми хочемо відкинути 7 їх і залишити лише 3. Тому крім числа 3 ми маємо передати як параметр режим округлення ( rounding mode ). Всього у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— заокруглення у велику сторону, якщо число після коми >= .50.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5 -
ROUND_HALF_DOWN— округлення у велику сторону, якщо число після коми > .50.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
Порівняння великих чисел
Це питання також важливе. Ти вже пам'ятаєш, що для порівняння об'єктів Java використовується методequals(). Він або надається самою мовою (у разі вбудованих Java класів), або перевизначається програмістом. Але у випадку з об'єктами класів BigDecimalвикористовувати метод equals()порівняння не рекомендується. Причина цього в тому, що метод BigDecimal.equals()двох чисел повертає true тільки у випадку, якщо 2 числа мають однакове значення та масштаб (scale) : Давай порівняємо поведінку методів 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 Як бачиш, числа 1.5 і 1.50 у випадку BigDecimalвиявабося нерівними! Це сталося саме через специфіку роботи методу 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. Це той результат, на який ми розраховували! :) На цьому наше сьогоднішнє заняття закінчено. Саме час повернутися до завдань! :)
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ