Максимальне використання чисел за допомогою десяткових знаків

Одним із найпоширеніших типів даних у Python є тип `float`, який використовується для представлення чисел з рухомою комою. Такі числа можуть бути як позитивними, так і від’ємними, і відрізняються наявністю десяткової частини. Крім того, `float` охоплює числа, записані в науковій нотації, де символ `e` або `E` вказує на ступінь десятки.

Тип даних `float` є надзвичайно важливим, адже він здатний представляти широкий спектр дійсних чисел, від дуже малих до надзвичайно великих.

Нижче наведено кілька прикладів чисел з рухомою комою в Python:

        # Приклади чисел float
        a = 20.0
        b = -51.51345
        c = 65e7
        d = -1.08E12
        e = 2E10

        print(type(a))
        print(type(b))
        print(type(c))
        print(type(d))
        print(type(e))
    

Вивід:

        <class 'float'>
        <class 'float'>
        <class 'float'>
        <class 'float'>
        <class 'float'>
    

Значення типу `float` дозволяють проводити обчислення з більшою точністю, ніж цілі числа, які відкидають дробову частину. Наприклад, число 3,142 буде представлено цілим числом як 3, тоді як `float` збереже його як 3,142. Тому, тип `float` краще підходить для математичних розрахунків, забезпечуючи більш точні результати.

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

Цілі числа (int) проти чисел з рухомою комою (float) у Python

Цілі числа, позначені як `int`, є ще одним популярним типом даних у Python. На відміну від чисел з рухомою комою, вони не мають десяткової частини. `int` включає позитивні, від’ємні числа та нуль, всі вони без дробової частини.

Цілі числа корисні, коли потрібні операції з цілими числами, наприклад, підрахунок або індексація.

Приклади цілих чисел:

        a = 0
        b = 968
        c = -14

        print(type(a))
        print(type(b))
        print(type(c))
    

Вивід:

        <class 'int'>
        <class 'int'>
        <class 'int'>
    

Основні відмінності між цілими числами та числами з рухомою комою в Python:

Характеристика Цілі числа (int) Числа з рухомою комою (float)
Представлення Цілі числа, їх від’ємні аналоги та нуль, без десяткової коми. Реальні числа з десятковою комою.
Точність Необмежена точність, немає обмежень на довжину або величину. Єдине обмеження – доступна пам’ять. Обмежена точність. Найбільше значення, яке можна зберегти, приблизно 1.8 x 10308.
Використання пам’яті Використовує менше пам’яті, ніж float. Використовує більше пам’яті, ніж int.
Побітові операції Активно використовуються в побітових операціях. Майже ніколи не використовуються в побітових операціях.
Застосування Використовуються для підрахунку, індексування та побітових операцій. Застосовуються у вимірюваннях, наукових розрахунках та більшості математичних операцій.

Різні способи створення та використання float у Python

Найпростіший спосіб створити змінну типу `float` – це присвоїти їй значення з рухомою комою:

        # Присвоєння змінній значення float
        a = 3.142
    

Інший спосіб – перетворення цілих чисел або рядків, які представляють числа, в `float` за допомогою конструктора `float()`. Передаючи ціле число чи числовий рядок у `float()`, ми отримаємо відповідне значення з рухомою комою:

        number1 = 2524
        numString1 = "513.523"
        numString2 = "1341"
        # Перетворення в float та збереження результату у змінну
        a = float(number1)
        print(a)
        b = float(numString1);
        print(b)
        c = float(numString2)
        print(c)
    

Вивід:

        2524.0
        513.523
        1341.0
    

В цьому прикладі, ціле число та рядки перетворюються у значення з рухомою комою за допомогою `float()`, і результат зберігається у відповідній змінній, яка потім виводиться на екран.

Ще одним способом отримати `float` є виконання математичних операцій, зокрема ділення:

        num1 = 20
        num2 = 3
        result = num1/num2
        print("Результат ділення як ціле число:")
        print(int(20/3))
        print("Результат ділення як число з рухомою комою:")
        print(result)
        print(type(result))
    

Вивід:

        Результат ділення як ціле число:
        6
        Результат ділення як число з рухомою комою:
        6.666666666666667
        <class 'float'>
    

Як видно з прикладу, результат ділення, представлений як `float`, дає точнішу відповідь порівняно з результатом, обчисленим як ціле число.

При роботі зі значеннями `float` у Python можуть виникати цікаві особливості, що пов’язані зі способом їх внутрішнього представлення в комп’ютері. Числа з рухомою комою зберігаються в апаратному забезпеченні як двійкові дроби.

Однак, більшість десяткових дробів, особливо з періодичною частиною, неможливо точно представити у вигляді двійкового дробу. З цієї причини, значення `float` зазвичай зберігаються як наближення їхньої фактичної величини.

Наприклад, якщо присвоїти змінній значення 0,3, воно не буде зберігатися як точне 0,3. Для наочності використаємо функцію `format()` для виведення внутрішнього представлення числа з різною кількістю знаків після коми. У прикладі нижче, виведемо 0,3 з 20 знаками, щоб побачити, як воно зберігається всередині.

        num = 0.3
        print("num з 20 знаками після коми")
        print(format(num, '.20f'))
        print("Значення, що ми зберегли для num")
        print(num)
    

Вивід:

        num з 20 знаками після коми
        0.29999999999999998890
        Значення, що ми зберегли для num
        0.3
    

Як бачимо, значення 0,3, присвоєне змінній `num`, не зберігається точно як 0,3. При виведенні змінної `num` отримуємо заокруглене значення.

Через це можуть виникати неочікувані результати при роботі з `float`. Наприклад, 0,3 + 0,3 + 0,3 в результаті дадуть 0,9. Проте, Python може видати інший результат, оскільки він зберігає двійкові наближення фактичних значень. Це можна побачити нижче:

        sum = 0.3 + 0.3 + 0.3
        answer = 0.9
        print("Чи дорівнює sum значенню answer: ")
        print(sum == answer)
        print("Внутрішнє представлення sum: ")
        print(sum)
        print("Відповідь з ручних обчислень: ")
        print(answer)
    

Вивід:

        Чи дорівнює sum значенню answer:
        False
        Внутрішнє представлення sum:
        0.8999999999999999
        Відповідь з ручних обчислень:
        0.9
    

Тому при роботі зі значеннями `float` потрібно пам’ятати, що Python зберігає не точні значення, а їхні наближення.

Отже, при порівнянні значень з рухомою комою, доцільно округлювати їх до однакової кількості знаків після коми. Для більшої точності в обчисленнях рекомендується використовувати вбудований модуль `decimal`.

Модуль `decimal` у Python

У випадках, коли потрібна висока точність, наприклад у фінансових та наукових розрахунках, використання `float` може бути не найкращим варіантом. Щоб гарантувати точність при роботі з числами з рухомою комою, використовують модуль `decimal`.

На відміну від `float`, який зберігається як залежне від машини двійкове представлення з рухомою комою, модуль `decimal` зберігає числа, використовуючи машинно-незалежне десяткове представлення, що забезпечує вищу точність.

Модуль `decimal` представляє десяткові числа точно такими, якими вони є, та використовує їх в обчисленнях без спотворень. Він також забезпечує коректно округлену десяткову арифметику з рухомою комою.

Для початку використання модуля `decimal`, його потрібно імпортувати у ваш Python-файл:

        import decimal
    

Щоб побачити переваги модуля `decimal`, повторимо приклад з порівнянням суми 0,3 + 0,3 + 0,3 зі значенням 0,9:

        import decimal

        sum = decimal.Decimal('0.3') + decimal.Decimal('0.3') + decimal.Decimal('0.3')
        answer = decimal.Decimal('0.9')
        print("Чи дорівнює sum значенню answer:")
        print(sum == answer)
        print("Внутрішнє представлення sum:")
        print(sum)
        print("Відповідь з ручних обчислень:")
        print(answer)
    

Вивід:

        Чи дорівнює sum значенню answer:
        True
        Внутрішнє представлення sum:
        0.9
        Відповідь з ручних обчислень:
        0.9
    

Отже, коли потрібна висока точність при роботі з числами з рухомою комою, варто використовувати модуль `decimal`.

Поширені помилки при роботі з float

Багато помилок при роботі з `float` у Python виникають через непорозуміння щодо їх внутрішнього представлення. Наприклад, значення 0,3 не буде збережене точно як 0,3. Тому, можна зіткнутися з помилками, якщо припускати, що числа з рухомою комою зберігаються в точності, як їх вказали.

Однією з поширених помилок є помилка округлення, яка виникає при виконанні математичних операцій з `float`. Оскільки Python не може точно представити значення з рухомою комою, то результати обчислень можуть відрізнятися від очікуваних.

Через такі помилки, як помилки округлення, можуть виникати проблеми при порівнянні значень на рівність. Будьте обережні при роботі з `float` і пам’ятайте про можливі неочікувані результати.

Найкращий спосіб уникнути помилок при роботі з `float` – це використовувати вбудований модуль `decimal`. У цьому випадку результати обчислень будуть більш передбачуваними та точними.

Висновок

Як програмісту, що працює з Python, вам обов’язково доведеться використовувати тип даних `float`. Щоб уникнути помилок, важливо розуміти, як Python внутрішньо представляє числа з рухомою комою. Оскільки Python не може зберігати фактичні значення `float`, уникайте точного порівняння на рівність, інакше можуть виникнути помилки.

Якщо для вашої програми потрібні точні результати, не використовуйте тип `float`. Замість цього застосовуйте вбудований модуль `decimal`, який забезпечує точні результати та представляє числа з рухомою комою точно, в машинно-незалежний спосіб.

Також рекомендуємо ознайомитися зі статтями про функції Python Itertools і Python Try Except.