JavaRush /Курси /JAVA 25 SELF /Вступ до дробових чисел і типу double

Вступ до дробових чисел і типу double

JAVA 25 SELF
Рівень 6 , Лекція 2
Відкрита

1. Дробові числа

Припустімо, ви вирішили написати найпростіший калькулятор. Або будь‑яку іншу програму, де потрібні обчислення (від банального підрахунку грошей до складної фізики). Далеко не все в реальному житті — ціле число, і з цим нічого не вдієш!

Озброїмося новим типом даних!

У програмуванні дробові числа ще називають дійсними або числами з плаваючою комою (floating-point). У Java, як і в більшості мов, їх використовують для зберігання не лише цілих, а й «дробових» значень: на кшталт 3.14, -28.57, 2.718281828

Дійсні числа мають два основні типи:

Тип Зберігає Діапазон значень (приблизно) Точність Типовий розмір
float
Числа ±1.5 × 10-45 … ±3.4 × 1038 ~7 знаків після крапки 4 байти
double
Числа ±5.0 × 10-324 … ±1.7 × 10308 ~15–16 знаків після крапки 8 байтів

Тип float

Тип float походить від поняття floating-point number — «число з плаваючою комою». У математиці дійсні числа мають певні властивості, натомість компʼютер має чимало обмежень. Тож не зовсім коректно називати дробові числа в Java дійсними — для них уживають назву «числа з плаваючою комою».

Тип float зазвичай зберігає 7 значущих цифр (наприклад, 0.1234567), показник ступеня десятки та займає 4 байти в памʼяті. Цього дуже мало для точних обчислень, тож усі швидко перейшли на числа подвійної точності.

Тип double

Назва типу double походить від «подвійна точність» (double). Він займає в памʼяті 8 байтів (удвічі більше, ніж float) і може зберігати до 15 значущих цифр: 0.123456789012345. Цього більш ніж достатньо для більшості обчислень із дробовими числами, тому double є основним типом для зберігання дробових чисел у Java.

У цій лекції зосередимося на типі double: його рекомендують використовувати за замовчуванням для всіх «звичайних» дробових чисел. Втім, далі розглянемо й тип float.

2. Оголошення й ініціалізація змінних типу double

Усе, як і з int — лише тепер використовуємо double.

// Оголошуємо змінну й присвоюємо їй значення Пі
double pi = 3.1415926;

// Можна оголосити й без ініціалізації
double averageSalary;
averageSalary = 91234.56;

// Можна обчислювати!
double pizzaPieces = 8;
double friends = 3;
double piecesPerFriend = pizzaPieces / friends; // 2.666… (а не 2)

Особливості синтаксису:

  • Як десятковий роздільник використовується крапка (3.14). Якщо використаєте кому — отримаєте помилку компіляції!
  • Точніше, записавши double d = 3;, ви не отримаєте помилку — відбудеться автоматичне перетворення типів (ціле число перетворюється на «дійсне» без втрат).

3. Введення й виведення дійсних чисел за допомогою Scanner

Спершу спробуємо вивести дробове число:

double amount = 42.75;
System.out.println(amount); // Виведе: 42.75

Усе гаразд! А якщо додати текст:

System.out.println("На вашому рахунку: " + amount + " євро."); // На вашому рахунку: 42.75 євро.

Введення з клавіатури

Для введення double потрібно використовувати спеціальний метод класу Scanner: console.nextDouble().

Scanner console = new Scanner(System.in);

System.out.println("Введіть температуру за вікном:");
double temperature = console.nextDouble(); // Одразу вводимо double

System.out.println("Зараз надворі: " + temperature + " градусів.");

4. Тип double у дії: арифметика

Усі звичні операції (+, -, *, /) працюють так само, як і для int:

double distance = 100.5;
double time = 2.0;
double speed = distance / time; // 50.25

System.out.println("Середня швидкість: " + speed); // Середня швидкість: 50.25

Ось і вся арифметика. Єдина відмінність: результат ділення — завжди дробове число, якщо хоча б один із операндів — double.

Порівняємо з int

int a = 5, b = 2;
System.out.println(a / b); // 2 (залишок відкидається)

double aa = 5, bb = 2;
System.out.println(aa / bb); // 2.5

5. Типові помилки та «дивини» під час роботи з double

Помилка під час перетворення введених даних

Класична ситуація: користувач вводить 3,14, а програма очікує 3.14. У Java метод Scanner.nextDouble() орієнтується на поточну локаль: у німецькій локалі кома допустима, в англійській — потрібна крапка. За потреби налаштуйте локаль для Scanner або прочитайте рядок і розберіть його вручну.

// Це спричинить проблему в Locale.US, якщо введено «3,14»
double value = console.nextDouble();

«Неточність» чисел у компʼютері

Ось тут у новачків зазвичай починається легке здивування:

double x = 0.1 + 0.2;
System.out.println(x); // Гм… 0.30000000000000004

Вітаю, ви зіткнулися з «магією» подання дробових чисел усередині компʼютера. Річ у тому, що багато чисел неможливо точно подати у двійковій системі. Зазвичай це не критично для більшості застосунків, але є нюанси у фінансах і точних науках.

6. Важливо: double і int — автоматичне та явне перетворення

Буває, ви додаєте ціле до дробового або присвоюєте int змінній double — помилок не буде:

int i = 2;
double d = i; // Усе гаразд!
System.out.println(d); // 2

double dd = 3.7;
int ii = (int) dd; // Потрібно явно перетворити тип double на тип int!
System.out.println(ii); // 3, дробова частина відкинулася

Часто це дивує: чому після перетворення дробова частина зникла? Просто тому, що тип int не вміє зберігати дроби (усе, що після крапки, зникло назавжди).

Детальніше про перетворення double у int і оператор (int) — у наступній лекції.

7. Форматоване виведення: красиво виводимо double

Часто за замовчуванням double виводиться з надлишком нулів. Можна відформатувати виведення:

double temp = 23.56789;
System.out.println(temp); // 23.56789

// 2 знаки після крапки
System.out.println(String.format("%.2f", temp)); // 23.57

// 1 знак після крапки
System.out.println(String.format("%.1f%n", temp)); // 23.6
Формат Результат Опис
"%.2f"
23.57 число з 2 знаками після крапки
"%.1f"
23.6 число з 1 знаком після крапки

8. Типові помилки під час роботи з float і double

Помилка № 1: неявне перетворення double у float

float f = 1.23; // Помилка!

Компілятор видасть помилку: «Ви намагаєтеся присвоїти double змінній float — це може призвести до втрати точності!» Завжди додавайте суфікс f.

Помилка № 2: забули, що ділення двох int дає цілочисельний результат

int a = 7, b = 2;
double result = a / b; // 3.0, а не 3.5

Щоб отримати дробову частину, явно перетворіть принаймні один операнд:

double result = (double) a / b; // 3.5

Помилка № 3: порівняння дробових чисел

Не порівнюйте дробові числа на рівність за допомогою ==. Використовуйте порівняння з невеликим допуском (epsilon).

Помилка № 4: втрата точності у float

Не зберігайте великі числа або дуже точні значення у типі float — вони можуть спотворитися або «втратити» важливі цифри.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ