JavaRush /Курси /Модуль 1: Python Core /Робота з дійсними числами

Робота з дійсними числами

Модуль 1: Python Core
Рівень 4 , Лекція 3
Відкрита

4.1 Округлення дійсних чисел

Дійсні (дробові) числа англійською називаються floating point number — числа з плаваючою точкою: в США для розділення цілої і дробової частини числа використовується точка. Звідси й походить назва float.

Як ми вже розбирали, при перетворенні дійсного числа (float) в ціле (int), воно завжди округлюється вниз до цілого — його дробова частина просто відкидається. Але легко уявити ситуацію, коли дробове число потрібно округлити просто до найближчого цілого. Що робити в такій ситуації?

Для цього в Python є вбудована функція round(). Вона була придумана ще до створення бібліотеки math, тому не входить в неї. Функції для округлення вниз і округлення вгору знаходяться в бібліотеці math.

Функція round() округлює число до найближчого цілого:


round(дійсне_число)

Ця функція поверне ціле число, до якого ближче передане в неї дійсне число. Важливо зазначити, що якщо дробова частина числа дорівнює 0.5, функція round() використовує метод округлення до найближчого парного цілого числа. Це називається "банківським округленням" і дозволяє зменшити систематичну помилку при багаторазовому округленні. Наприклад:

Приклади:

Команда Результат
x = round(4.1) 4
x = round(4.5) 4
x = round(4.9) 5
x = round(5.5) 6
Функція math.ceil() округлює число до цілого вгору, приклади:

Команда Результат
x = math.ceil(4.1) 5
x = math.ceil(4.5) 5
x = math.ceil(4.9) 5

Функція math.floor() округлює число до цілого вниз, приклади:

Команда Результат
x = math.floor(4.1) 4
x = math.floor(4.5) 4
x = math.floor(4.9) 4

Хоча для округлення числа до цілого вниз простіше використовувати функцію перетворення типів int():

Команда Результат
x = int(4.9) 4

Якщо вам складно запам'ятати ці команди, допоможе невеликий урок англійської:

  • math — математика
  • round — круг/округляти
  • ceiling — стеля
  • floor — підлога

4.2 Влаштування чисел з плаваючою точкою

Тип float в Python може зберігати значення в діапазоні -1.7*10308 до +1.7*10308. Такий гігантський діапазон значень пояснюється тим, що тип float влаштований зовсім інакше у порівнянні з цілими типами. Кожна змінна типу float містить два числа: перше називається мантиса, а друге — ступінь.

Припустимо, у нас є число 123456789, і ми зберегли його в змінну типу float. Тоді число буде перетворене на вигляд 1.23456789*108, і всередині типу float будуть зберігатися два числа — 23456789 і 8. Червоним виділено «значущу частину числа» (мантиса), зеленим — ступінь.

Такий підхід дозволяє зберігати як дуже великі числа, так і дуже маленькі. Але оскільки розмір числа обмежений 8 байтами (64 біта) і частина біт використовується для зберігання ступеня (а також знака числа і знака ступеня), максимальна довжина мантиси обмежена 15 цифрами.

Це дуже спрощений опис влаштування дійсних чисел, більш повний можна загуглити.

4.3 Втрата точності при роботі з дійсними числами

При роботі з дійсними числами завжди потрібно мати на увазі, що дійсні числа — неточні. Завжди будуть помилки округлення, помилки перетворення з десяткової системи в двійкову і, нарешті, найчастіше — втрата точності при додаванні/відніманні чисел занадто різних розмірностей.

Останнє — найнеочікуваніша ситуація для новачків у програмуванні.

Якщо з числа 109 відняти 1/109, ми отримаємо знову 109.

Віднімання чисел занадто різних розмірностей Пояснення

1000000000.000000000
   -     0.000000001
1000000000.000000000
                            
Друге число занадто маленьке, і його значуща частина ігнорується (виділено сірим). Червоним виділено 15 значущих цифр.

Що тут сказати, програмування — це не математика.

4.4 Небезпека порівняння дійсних чисел

Ще одна небезпека підстерігає програмістів при порівнянні дійсних чисел. Оскільки при роботі з цими числами можуть накопичуватися помилки округлення, то можливі ситуації, коли дійсні числа повинні бути рівні, але вони не рівні. І навпаки: числа повинні бути не рівні, але вони рівні.

Приклад:

Команда Пояснення
a = 1000000000.0 b = 0.000000001 c = a – b

У змінній a буде значення 1000000000.0

У змінній c буде значення 1000000000.0

(число в змінній b занадто маленьке)

У наведеному вище прикладі a та c не повинні бути рівні, але вони рівні.

Або візьмемо інший приклад:

Команда Пояснення
a = 1.00000000000000001 b = 1.00000000000000002

У змінній a буде значення 1.0

У змінній b буде значення 1.0

На практиці дійсні числа порівнюють так:

Береться якесь дуже маленьке число. Якщо різниця чисел (по модулю) менша, ніж це маленьке число, то вони вважаються рівними. Приклад:


a = 0.00000000012
b = 0.000000000011 

if abs(a - b) < 0.00001:
    print("рівні")
else:
    print("не рівні")
Коментарі (10)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Дмитро Рівень 30
26 вересня 2025
В задачі "Порівнювати дуже просто", я повинен вміти читати думки того хто писав завдання? Сказано порівняти числа з допустимою epsilon. Не вірно! І вже коли автоперевіпка каже що не вірно, от після цього сказали що epsilon повинен бути 0.00001. А відразу це в завданні написати руки відсохнуть? В мене сильно пригорає, коли код пишеш вірно, але тобі кажуть що ні, не так, ми хотіли щоб ти зробив ось так. Але в самому завданні, це чомусь не пишеться. В "Круглий математик" теж прикол, Прочитав умову, написав код. Не вірно. Бо змінну обізвав "num" замість "number". Після таких приколів, складається враження, що при навчанні, одна з задач, максимально познущатися на тобою.
Vira Рівень 14
9 жовтня 2025
Тут головне НАВЧИТИСЯ писати код, а не тестувати автоперевірку
Дмитро Рівень 30
9 жовтня 2025
Уууу, у вас ще все попереду))) Писати код то я вмію. Якраз через те що вже вмію, і не так як хочуть розробники автоперевірки, від цього і підгорає. І я не один такий. Одна людина добре і лаконічно підмітила: "Все сводится к тому что я должен не просто решить задачу, а угадать какой именно вариант решения от меня ожидает платформа."
Максим Рівень 9
11 березня 2025
ось у нас є частина прикладу:

a = 0.00000000012
b = 0.000000000011

if abs(a - b) < 0.00001:
    print("рівні")
else:
    print("не рівні")
Як я розумію то тут порівняння працює лише при умовах що а більша ніж b, вірно?
Roma Zastavnyi Рівень 13
10 листопада 2025
Ні. Тут використовується функція abs, вони працює як модуль (здається) в математиці, тобто число лишається позитивне. Тому не важливо яке буде більше число, результат не буде негативним.
Віталій Рівень 23
9 березня 2025
хтось знає звідки взялось - "epsilon = 1e-9" ?
Максим Рівень 9
12 березня 2025
тут показували:

if abs(a - b) < 0.00001:
    print("рівні")
else:
    print("не рівні")
Павло Левко Рівень 17
15 грудня 2024
чому round(4.5) = 4 ?
Bandiu Band Рівень 25
27 грудня 2024
бо round, округлює до найближчого парного числа, в данному випадку це 4 бо 5 непарне. Якщо хочеш округлення як в школі тоді використовуй ceil, але при роботі з великою кількістю данних буде накоплюватись похибка.
Vira Рівень 14
9 жовтня 2025
ceil заокруглює вгору, а не як в школі; щоб було як в школі, то можна написати функцію самостійно