logo

Помилка з плаваючою комою в Python

Python, широко поширена мова програмування, відмінно справляється з чисельними обчислювальними завданнями, але вона не застрахована від проблем, пов’язаних з арифметикою з плаваючою комою. Числа з плаваючою комою в Python є наближеннями дійсних чисел, що призводить до помилки округлення, втрата точності та скасування що може порушити розрахунки. Ми можемо виявити ці помилки, шукаючи дивні результати і за допомогою інструментівnumpy.finfo>до точність моніторингу . З певною обережністю та хитрими трюками ми можемо тримайте ці помилки під контролем і переконайтеся, що наші обчислення Python надійні. У цій статті ми дослідимо тонкощі помилок із плаваючою комою Python .

Що таке числа з плаваючою комою?

Числа з плаваючою комою є ефективним способом представлення дійсних чисел у комп’ютерах. Вони складаються з трьох частин:



  • Значні: Фактичні цифри, що представляють число (наприклад, 3,14159)
  • Експонента: Повідомляє, на скільки місць потрібно зсунути значуще вліво або вправо (наприклад, -2 у 3,14159 x 10^-2)
  • база: Зазвичай 2 для комп’ютерів, що визначає, як числа представлені всередині

Чому виникають помилки з плаваючою комою?

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

  • Кінцева точність: Лише обмежена кількість цифр може зберігатися в значущому, що веде до помилки округлення при поданні точних десяткових дробів.
  • Втрата точності: Такі операції, як додавання чи віднімання, можуть ще більше знизити точність, посилюючи ефект округлення.
  • Нижній/переливний: Надзвичайно малі чи великі числа можуть виходити за межі репрезентованого діапазону, що призводить до недоплив (стає нульовим) або перелив (стає нескінченністю).

Типи помилок із плаваючою комою

а) Помилки округлення: Найпоширеніший, коли необхідно наблизити точне десяткове число, щоб відповідати обмеженій точності числа з плаваючою точкою.

b) Втрата точності: Подальші операції можуть поступово накопичувати помилки округлення, що призводить до значних неточностей кінцевого результату.



c) Катастрофічне скасування: Під час віднімання майже рівних чисел із протилежними знаками їхні значущі цифри компенсуються, залишаючи маленький і неточний результат.

додавання рядка в java

d) переповнення/переповнення: Це відбувається, коли обчислення виходять за межі репрезентованого діапазону плаваючих значень, що призводить до неточних або безглуздих результатів.

Виявлення помилок із плаваючою комою

  1. Спостереження за неочікуваними результатами: Порівняння обчислених значень із очікуваними результатами або візуалізація даних може виявити невідповідності, які часто викликані помилками.
  2. Використання таких бібліотек, як numpy.finfo> : Бібліотеки люблятьnumpy>надати такі інструменти, якfinfo>щоб перевірити точність і обмеження різних типів даних float.

Помилка з плаваючою комою Python

Тут ми обговоримо різні типи прикладів, які ілюструють помилки з плаваючою комою в Python:



Втрата точності при перетворенні десяткової системи в двійкову

У цьому прикладі десяткове число 0,1 перетворюється на двійкове. Через нескінченне двійкове розширення 0,1 використовується лише кінцева кількість бітів, що призводить до втрати точності.

Python3




decimal_number>=> 0.1> binary_representation>=> format>(decimal_number,>'.30f'>)># 30 decimal places> print>(f>'Decimal: {decimal_number} Binary: {binary_representation}'>)>

>

>

Вихід:

Decimal: 0.1 Binary: 0.100000000000000005551115123126>

Помилки округлення

Тут результат додавання 1/3 три рази очікується як 1,0. Однак через помилки округлення при представленні 1/3 сума може бути неточною 1,0.

Python3




result>=> 1.0> /> 3.0> sum_result>=> result>+> result>+> result> print>(f>'Expected Result: 1.0 Actual Result: {sum_result}'>)>

>

>

Вихід:

Expected Result: 1.0 Actual Result: 1.0>

Накопичувальні помилки в ітераційних обчисленнях

Цей приклад демонструє, як можуть виникнути накопичувальні помилки в ітеративних обчисленнях. Додавання 0,1 десять разів може не дати точного результату 1,0 через обмеження точності числа з плаваючою комою.

Python3




total>=> 0.0> for> i>in> range>(>10>):> >total>+>=> 0.1> print>(f>'Expected Result: 1.0 Actual Result: {total}'>)>

ymail
>

>

Вихід:

Expected Result: 1.0 Actual Result: 0.9999999999999999>

Проблеми порівняння

У цьому випадку порівняння суми 0,1 і 0,2 з 0,3 може не дати очікуваногоTrue>результат через притаманну неточність чисел з плаваючою комою.

Python3




a>=> 0.1> +> 0.2> b>=> 0.3> print>(f>'a: {a} b: {b} Equal: {a == b}'>)>

>

>

Вихід:

a: 0.30000000000000004 b: 0.3 Equal: False>

Несподівані результати в розрахунках

Тут віднімання1e16>від суми(1e16 + 1)>Очікується, що дасть 1, але через помилки з плаваючою комою результат може бути не точно 1.

Python3




a>=> 0.1> +> 0.2> b>=> 0.3> print>(f>'a: {a} b: {b} Equal: {a == b}'>)>

>

>

Вихід:

Expected Result: 1 Actual Result: 0.0>

Розуміння точності з плаваючою комою

Тут ми розберемося з точністю з плаваючою комою: Аномалія 1.2 – 1.0 у Python-

Виклики представництва

Як відомо, 1,2 – 1,0 = 0,2. Але коли ви спробуєте зробити те саме в Python, ви будете здивовані результатами:

>>> 1,2 - 1,0>>

Вихід:

0.199999999999999996>

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

10 / 3 = 3.33333333.......>

У цьому випадку, беручи 1.2 як приклад, подання 0.2 у двійковому вигляді буде 0.00110011001100110011001100…… і так далі. Це нескінченне десяткове число важко зберігати всередині. Зазвичай значення об’єкта з плаваючою комою зберігається у двійковій формі з плаваючою комою з фіксованою точністю ( зазвичай 53 біти ). Тож представляємо 1.2 внутрішньо як,

1.0011001100110011001100110011001100110011001100110011>

Що точно дорівнює:

1.1999999999999999555910790149937383830547332763671875>

Обробка помилки з плаваючою комою

Тут ми обговоримо різні приклади обробки помилок із плаваючою комою в Python:

рядок java для char

Округлення до певного десяткового знака

Округливши результат до певного десяткового знаку (наприклад, 2), ви можете пом’якшити вплив невеликих помилок із плаваючою комою.

Python3




result>=> 1.2> -> 1.0> rounded_result>=> round>(result,>2>)> print>(f>'Original Result: {result} Rounded Result: {rounded_result}'>)>

>

>

Вихід:

Original Result: 0.19999999999999996 Rounded Result: 0.2>

Використання десяткового класу для високої точності

Thedecimal>модуль забезпечуєDecimal>класу, що забезпечує більш точну арифметику. Встановлення точності зgetcontext().prec>може допомогти в управлінні точністю для конкретних обчислень

Python3




from> decimal>import> Decimal, getcontext> getcontext().prec>=> 4> # Set precision to 4 decimal places> result>=> Decimal(>'1.2'>)>-> Decimal(>'1.0'>)> print>(f>'High Precision Result: {result}'>)>

>

>

Вихід:

High Precision Result: 0.2>

Використання дробів для точних представлень

Thefractions>модуль дозволяє працювати з точними дробовими представленнями, уникаючи помилок з плаваючою комою.

Python3




from> fractions>import> Fraction> result>=> Fraction(>'1.2'>)>-> Fraction(>'1.0'>)> print>(f>'Exact Fractional Result: {result}'>)>

>

concat рядки java
>

Вихід:

Exact Fractional Result: 1/5>

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

ВикористовуватиDecimal>клас для проміжних обчислень, щоб мінімізувати сукупні помилки перед перетворенням назад у float.

Python3




from> decimal>import> Decimal, getcontext> getcontext().prec>=> 6> # Set precision to 6 decimal places> intermediate_result>=> Decimal(>'1.2'>)>-> Decimal(>'1.0'>)> final_result>=> float>(intermediate_result)># Convert back to float if needed> print>(f>'Intermediate Result: {intermediate_result} Final Result: {final_result}'>)>

>

>

Вихід:

Intermediate Result: 0.2 Final Result: 0.2>

Висновок

Ви все одно думаєте чому python не вирішує цю проблему , насправді це не має нічого спільного з python. Це відбувається тому, що базова платформа c обробляє числа з плаваючою комою, і, зрештою, через неточність ми завжди будемо записувати числа у вигляді рядка з фіксованою кількістю цифр. Зауважте, що це в самій природі двійкового числа з плаваючою комою: це також не є помилкою Python або C , і це також не помилка у вашому коді. Ви побачите однакову поведінку в усіх мовах, які підтримують арифметику з плаваючою комою нашого обладнання, хоча деякі мови можуть не відображати різницю за замовчуванням або в усіх режимах виводу). Ми повинні враховувати цю поведінку, коли ми дбаємо про математичні задачі, які потребують точної точності, або використовуємо це в умовних операторах. Перевірте з плаваючою комою у розділі документації python для більшої кількості подібних дій.

Часті запитання (FAQ)

1. Що таке помилка з плаваючою комою в Python?

Помилка з плаваючою комою в Python стосується розбіжностей між очікуваними та фактичними результатами під час роботи з числами з плаваючою комою, що виникає через обмеження представлення дійсних чисел у двійковій системі.

2. Чому 1.2 - 1.0> не рівні 0.2> на Python?

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

3. Чи є помилка з плаваючою комою помилкою в Python?

Ні, це не помилка в Python. Це поширена проблема в обчисленнях, пов’язана з внутрішнім представленням чисел з плаваючою комою. Python дотримується стандарту IEEE 754 для арифметики з плаваючою комою.

4. Як я можу округлити результат із плаваючою комою до певного десяткового знаку?

Ви можете використовуватиround()>функція округлення результату з плаваючою комою до певного десяткового знаку. Наприклад,rounded_result = round(result, 2)>.

5. Що decimal> і як він допомагає обробляти помилки з плаваючою комою?

Thedecimal>модуль забезпечуєDecimal>клас для вищої точності арифметики. Встановлення точності та використанняDecimal>може допомогти зменшити помилки з плаваючою комою.