3.3. Приклад Румпа.
В 1988 р. проф. Зігфрид Румп, співробітник німецького відділення фірми IBM, досліджуючи алгоритми обчислень з гарантованими межами інтервалів, які містять заздалегідь відомий правильний результат, отримав поліном, який за певного співвідношення значень змінних дає однозначно неправильний результат для всіх стандартних форматів чисел з плаваючою комою [3].
, (4.1)
де = 77617, = 33096.
Використовуючи різні формати чисел з плаваючою комою на стандартній для того часу великій обчислювальній системі IBM S/370 для даного поліному було отримано приблизно однакові результати:
32 біт: = +1,172604;
64 біт: = +1,1726039400531786;
128 біт: = +1,1726039400531786318588349045201838.
Такі результати позволяють вважати, що надійний результат - приблизно 1,172603, або навіть 1,172603940053. Однак насправді правильний результат (в межах одиниці останньої цифри) відрізняється від продемонстрованих вище не тільки значенням, але навіть і знаком (!):
= -0,827396059946821368141165095479816...
Причиною такої розбіжності є те, що в даному випадку значення та задовільняють простій умові:
, (4.2)
а підставивши це значення в (4.1) маємо:
. (4.3)
Число = 7917111340668961361101134701524942848 - 37-ми значне. Це означає, що 34-х значущих цифр формату 128 біт недостатньо для того, щоби представити це число точно, тому похибка представлення числа порядку 1000 набагато перевищує число 2. Таким чином ці числа знаходяться в таких діапазонах представлення, здійснення арифметичних дій між числами із яких є некоректним. В результаті виконання дій в форматі 128 біт ми отримуємо
(4.4)
Даний приклад став класичною ілюстрацією тих проблем, які притаманні сучасним обчисленням з плаваючою комою. Обчислення полінома Румпа на комп'ютерах з процесорами Pentium та Sun Sparc дало різний результат в залежності від того, яка система комп'ютерної математики використовувалась.
Наприклад, обчислення полінома Румпа на базі програми, отриманої за допомогою компілятора Fortran 95 фірми Sun Microsystem Inc., дали такі результати:
32 біт: = −6. 338253∙1029;
64 біт: = −1. 1805916207174113∙1021;
128 біт: = +1. 1726039400531786318588349045201838.
Пізніше Румп показав [4], що аналогічні проблеми виникають і в випадку більш простого полінома (за аналогічних значень та ):
(4.5)
Особливу занепокоєність такого роду результати викликають в зв'язку з широким розповсюдженням за останній час обчислень на базі графічних процесорів (GPU), які для досягнення максимальної продуктивності, як правило, оперують з числами тільки одинарної точності, що різко підвищує ймовірність отримання неправильних результатів. Це не є критично для розрахунків, пов'язаних з побудовою графічних зображень, однак графічні процесори дедалі частіше використовуються для побудови високопродуктивних паралельних обчислювальних систем, які можуть складатися із десятків тисяч подібних процесорів, оскільки вони і дешеві, і швидкісні. Найбільш тривожним фактом є те, що практично в усіх математичних пакетах не тільки результат прикладу Румпа є неправильним, але і відсутні будь-які ознаки того, що під час обчислення виникли проблеми. А це означає, що такого роду помилок, які важко помітити може бути непередбачена кількість.
Одним із способів отримання правильного результату для прикладу Румпа є використання символьних обчислень. В даному контексті це означає, що при обрахунку полінома дійсні числа представляються не в традиційному форматі з плаваючою крапкою, а в вигляді раціональних дробів. В такому випадку поліном Румпа набуває вигляду:
, (4.6)
Якщо для обрахунків використовувати саме таку формулу, наприклад в пакеті Maple 8, то отримаємо правильний результат:
(4.7)
Однак символьні обчислення не завжди допомагають вирішити обчислювальну проблему. Якщо в вираз входить функція, яка повертає ірраціональний результат (логарифм, синус, радикал тощо), то її перетворення до дробового вигляду гарантовано привело би до похибки, і така нефіксована втрата точності стала би причиною отримання невірного результату.
Ще одним способом отримання правильного результату є використання під час обчислень такої розрядності представлення даних, яка суттєво перевищує стандартну. Для приклада Румпа 37-ми значне число в формулі (4.3) вимагає бітів для його повного представлення (див. Лабораторна робота №3, розділ 3.3), що є дещо більше, ніж 112+1 біт, який виділяється на мантису в форматі числа з плаваючою комою ІЕЕЕ754 128-біт.
Таким чином ми приходимо до необхідності форматів чисел з довжиною, що перевищує 128 бітів. Сучасні мови програмування можуть працювати з надзвичайно довгими цілими числами, Наприклад клас cBigNumber, який реалізує цілі числа необмеженої розрядності для С++ і в якому передбачені всі стандартні операції мови С++, а за допомогою цілих чисел можна реалізовувати і дійсні числа.
Питання полягає тільки в тому, яким чином визначити критерій необхідності застосування того, чи іншого формату чисел для ефективної роботи програми, оскільки збільшення розрядності представлення вдвічі означає збільшення часу виконання арифметичних дій більше, ніж вдвічі. В цьому контексті проблема, поставлена Румпом, залишається відкритою.
Yandex.RTB R-A-252273-3
- 2. Обладнання
- 3. Короткі відомості з теорії
- 3.1. Основні недоліки стандарту іеее754-1985.
- 3.2. Четверний (128-бітний) формат.
- 3.3. Приклад Румпа.
- 3.4. Особливості стандарту іеее Std 754-2008.
- 3.5. Бінарні формати стандарту іеее Std 754-2008.
- 3.5. Принципи представлення десяткових чисел з плаваючою комою.
- 3.6. Двійково-десяткове кодування.
- 3.7. Щільно упаковані десяткові числа.
- 3.8. Десяткові числа з плаваючою комою стандарту іеее754-2008.
- 3.9. Властивості десяткових чисел з плаваючою комою.
- 3.10. Формати десяткових чисел з плаваючою комою стандарту іеее754-2008.
- 4. Порядок виконання роботи.
- 5. Контрольні запитання.