ПРОБЛЕМИ ТОЧНОСТІ ОБЧИСЛЕНЬ В CPYTHON - Наукові конференції

Вас вітає Інтернет конференція!

Вітаємо на нашому сайті

Рік заснування видання - 2011

ПРОБЛЕМИ ТОЧНОСТІ ОБЧИСЛЕНЬ В CPYTHON

14.07.2024 12:37

[1. Інформаційні системи і технології]

Автор: Дейнеко Денис Павлович, аспірант кафедри програмного забезпечення компʼютерних систем, Чернівецький національний університет, м. Чернівці, Україна; Воробець Георгій Іванович, кандидат фізико-математичних наук, доцент кафедри комп’ютерних систем та мереж Чернівецький національний університет, м. Чернівці, Україна


ORCID: 0000-0001-8125-2047 Воробець Г.І.

АНОТАЦІЯ. Існує багато способів представлення або запису чисел. Наприклад, десяткові числа, римські цифри, наукова нотація, логарифмічна шкала і навіть позначки — це все способи представлення чисел. Математика має нескінченну точність при описі чисел. Наприклад, √2 — це саме те число, яке при зведенні до квадрату дає 2, точне десяткове представлення якого вимагає нескінченної кількості цифр. Це створює значну проблему для комп'ютерних систем, оскільки вони мають обмежену кількість памʼяті для зберігання чисел і не можуть розуміти абстрактні позначення, які людина використовує для більш компактного представлення чисел. Це дослідження висвітлює способи представлення чисел в інтерпретаторі CPython, а також існуючі помилки пов'язані з округленням та представленням чисел.

ОСНОВНА ЧАСТИНА. Кількість бітів зазвичай фіксована для будь-якій комп'ютерній системі. Використання двійкового представлення надає нам недостатній діапазон і точність чисел для проведення інженерних розрахунків. Щоб досягти необхідного діапазону значень з тією ж кількістю бітів, ми використовуємо числа з плаваючою крапкою або скорочено float. Замість того, щоб використовувати кожен біт як коефіцієнт степені 2, float виділяє біти на три різні частини: 

s — індикатор знака, який вказує, чи є число додатним або відʼємним; 

e — характеристику або експоненту, яка є степенем 2;

f — дробову частину, яка є коефіцієнтом експоненти. 

Майже всі реалізації Python відображають числа з плаваючою крапкою в форматі з подвійною точністю IEEE 754 — всього 64 біти. На індикатор знака виділяється 1 біт, для експоненти виділяються 11 бітів, і 52 біти виділяються для дробової частини. Якщо для експоненти виділяється 11 біт, це дає 2048 значень, які може набувати це число. Оскільки ми хочемо мати можливість створювати дуже точні числа, деякі з цих значень повинні представляти відʼємні експоненти, тобто дозволяти числа, які знаходяться між 0 і 1 в десятковій системі числення. Щоб досягти цього, 1023 віднімаємо від експоненти для її нормалізації. Значення, яке віднімається від експоненти, зазвичай називається зсувом. Дробова частина є числом між 1 і 2. У двійковій системі це означає, що провідний член завжди буде 1, тому це марна трата бітів для його зберігання. Щоб зберегти місце, провідна 1 відкидається [1, 2, 3]. У CPython ми можемо отримати інформацію про числа з плаваючою комою, використовуючи пакет sys, як наведено нижче (рис. 1):




Рис. 1. Системний вивід інформації про тип float

Тоді float може бути представлений як:

n=(-1)S*2-1023*(1+f)  — для 64 бітних систем

Існують особливі випадки, коли e = 0 (тобто, e = 00000000000 у двійковій системі) і коли e = 2047 (тобто, e = 11111111111 у двійковій системі), які зарезервовані. Коли експонента дорівнює 0, провідна 1 у дробовій частині приймає значення 0. Результатом є денормалізоване число, яке обчислюється за формулою:

n=(-1)S*2-1022*(0+f)

Коли е = 2047 і дробова частина f є ненульовою, тоді результатом є NaN (Not a Number), що означає, що число не визначене. Коли е = 2047,  f = 0 і s = 0, результатом є +. Коли е = 2047,  f = 0 і s = 1, результатом є -.

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

Найпоширенішою формою помилки округлення є помилка представлення чисел з плаваючою комою [1, 2]. Простий приклад — представлення числа  . Ми знаємо, що   — це нескінченне число, але коли ми його використовуємо, зазвичай беремо лише скінченну кількість цифр. Наприклад, якщо використовувати лише 3.14159265, виникає помилка між цим наближенням і справжнім нескінченним числом. Інший приклад — 1/3, справжнє значення якого дорівнює 0.333333333…, незалежно від того, скільки десяткових цифр ми оберемо, виникає помилка округлення. Крім того, коли ми округлюємо числа багато разів, помилка накопичується. Наприклад, якщо округлити число 4.845 до двох десяткових знаків, отримаємо 4.85. Потім, якщо округлити його ще раз до одного десяткового знака, отримаємо 4.9, загальна помилка складе 0.55. Але якщо ми округлимо один раз до одного десяткового знака, отримаємо 4.8, і помилка складе 0.045.

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




Рис. 2. Приклад накопичення помилок округлення

ВИСНОВКИ. Обмежена точність чисел з плаваючою крапкою є фундаментальною властивістю їх представлення в пам'яті комп'ютера. Тому повністю усунути проблему обмеженої точності в CPython використовуючи існуючі типи даних —  неможливо. Існують способи, як можна пом'якшити ефект обмеженої точності при роботі з числами з плаваючою крапкою використовуючи модулі decimal та NumPy. Проте кардинально новим рішенням здатним усунути існуючі помилки в обчисленнях слід вважати розробку нового типу даних, який підтримує довільну точність та додавання його до стандартної бібліотеки CPython у якості нового типу даних або окремої бібліотеки.

Література:

1. Goldberg D. What every computer scientist should know about floating-point arithmetic. ACM Computing Surveys. 1991. Т. 23, № 1. С. 5–48. URL: https://doi.org/10.1145/103162.103163

2. Monniaux D. The pitfalls of verifying floating-point computations. ACM Transactions on Programming Languages and Systems. 2008. Т. 30, № 3. С. 1–41. URL: https://doi.org/10.1145/1353445.1353446

3. Lee W., Sharma R., Aiken A. Verifying bit-manipulations of floating-point. ACM SIGPLAN Notices. 2016. Т. 51, № 6. С. 70–84. URL: https://doi.org/10.1145/2980983.2908107



Creative Commons Attribution Ця робота ліцензується відповідно до Creative Commons Attribution 4.0 International License
допомога Знайшли помилку? Виділіть помилковий текст мишкою і натисніть Ctrl + Enter
Конференції

Конференції 2024

Конференції 2023

Конференції 2022

Конференції 2021



Міжнародна інтернет-конференція з економіки, інформаційних систем і технологій, психології та педагогіки

Наукова спільнота - інтернет конференції

:: LEX-LINE :: Юридична лінія

Інформаційне суспільство: технологічні, економічні та технічні аспекти становлення