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.
| Віднімання чисел занадто різних розмірностей | Пояснення |
|---|---|
|
Друге число занадто маленьке, і його значуща частина ігнорується (виділено сірим). Червоним виділено 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("не рівні")
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ