Міжнародний стандарт представлення чисел з плаваючою точкою в ЕОМ

Практично будь-яку мову програмування дає можливість використовувати в обчисленнях дробові числа. Коли справа стосується програмної реалізації чисельних методів або будь-яких інших обчислень на ЕОМ, важливим питанням є внутрішнє уявлення чисел, з яким доводиться працювати програмісту. Від цього головним чином залежить точність обчислень, а також їх швидкість.

Числа з плаваючою точкою

Числа з плаваючою точкою - загальноприйнята форма уявлення дійсних чисел в ЕОМ. Основними параметрами такої форми подання є підстава ступеня (base) і точність (precision). При цьому завжди потрібно, щоб підстава ступеня було цілим парним числом. Якщо і, то число 0.1 представляється у вигляді. Однак, очевидно, що при певних параметрах деякі числа не вдасться представити точно. Наприклад, при і те ж саме число 0.1 представляється приблизно в вигляді (оскільки в бінарному представленні число 0.1 має нескінченний вид).

У загальному випадку при заданих параметрах запис виду являє число

При цьому називається мантиссой числа і складається з позицій. Надалі під числом з плаваючою точкою ми будемо розуміти дійсні числа точно представимо в сенсі даної форми.

Існують ще два важливі параметри - максимальний і мінімальний показники ступеня $ "/> і" />. Таким чином, при фіксованих параметрах ми можемо уявити -e_ + 1 \ right) \ beta ^ p $ "/> різних чисел з урахуванням знака.

Введемо ще одну домовленість. Поки що уявлення чисел з плаваючою точкою неунікальні. Наприклад, при і число 0.1 можна представити як і як. Подання числа, в старшій позиції якого стоїть цифра, відмінна від нуля, ми будемо називати нормалізованим. Використання нормалізованих форм вирішує проблему неєдиним уявлення чисел з плаваючою точкою. (Однак, при такій домовленості виникає цікаве питання - як представляти 0?)

машинний епсилон

Як відомо, існує 2 види похибок обчислення - абсолютна і відносна (Помилки обчислень). Під відносною похибкою розуміється відношення

де - значення, отримане при округленні, а - точне значення обчислень.

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

При спробі написати нерівність для відносної похибки, що відповідає згаданій вище абсолютної похибки, нескладно отримати, що

Величину "/> прийнято називати машинним Епсілон (machine epsilon). Таким чином можна стверджувати, що при округленні дробового числа найближчим до нього числом з плаваючою точкою відносна похибка округлення не перевищує машинного Епсілон.

Існує й інше визначення. Машинний епсилон можна визначити як мінімальний позитивний число, яке будучи додано до одиниці дає результат відмінний від одиниці. Читачеві пропонується перевірити еквівалентність цих визначень самостійно.

стандарт IEEE

Існує два різних стандарту IEEE для чисел з плаваючою точкою. IEEE 754 - двійковий стандарт і вимагає, щоб, а для одинарної точності (single) і для подвійної точності (double). Також в стандарті IEEE 754 точно обговорено використання бітів при поданні чисел в одинарної і подвійної точності. У стандарті IEEE 854 може приймати значення 10 або 2. Також нічого не говориться про розподіл бітів між мантиссой і ступенем.

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

підстава ступеня

Вибір в якості підстави ступеня 10 не вимагає особливих роз'яснень. Десяткова система - система, звична для людини. У разі двійковій системи варто обговорити деякі переваги, властиві їй. Ми домовилися використовувати нормалізовані форми чисел. Якщо, то в старшій позиції може стояти тільки 1. Це дає нам можливість не зберігати цю одиницю в пам'яті і тим самим отримати додатковий біт для мантиси. У цьому випадку прийнято говорити, що стандарт використовує прихований біт (hidden bit).

Повернемося до питання про подання нуля в нормалізованому формі. Нуль відповідає нульовий мантисі і ступеня -1 "/>. Таким чином нуль представляється у вигляді.

точність уявлення

Стандарт IEEE пропонує 4 різних точності: одинарна (single), подвійна (double), одинарна розширена (single-extended) і подвійна розширена (double-extended). IEEE 754 жорстко обговорюють число біт одинарної і подвійної точності. Це означає, що на всіх ЕОМ, що підтримують IEEE 754, кількість біт в поданні чисел з одинарної точністю і з подвійною точністю фіксовані. Кількість біт розширених точностей жорстко не фіксується. Розширені формати покликані хоч трохи збільшити кількість біт на мантиссу і на показник ступеня. Нижче наведено таблицю параметрів різних точностей в стандарті IEEE.


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

Саме для таких випадків в стандарті IEEE існують спеціальні значення.

NaN (Not a number) використовується стандартом IEEE для обробки ситуацій виду вилучення кореня з негативного числа.

Наведемо невелику таблицю, що демонструє випадки повернення NaN.

Операції, які повертають NaN

Випадок, коли виникає NaN

У бітовому поданні NaN не обмовляється, яке значення має приймати мантиса. Єдине обмеження - вона не повинна бути нульовою. Цей факт використовується для передачі певної системної інформації через мантиссу. Таким чином існує багато різних значень виду NaN - кожне для свого випадку.

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

Наведемо хороший приклад, який демонструє важливість цього спеціального значення. Припустимо, що у нас є програма, що обчислює нулі функції. Ми хочемо реалізувати її так, щоб вона не вимагала інтервал пошуку в якості вхідного аргументу. Така реалізація може викликати проблему - що, якщо програма спробує обчислити значення функції поза області її визначення? Зокрема, програма може спробувати взяти квадратний корінь від -4. Якби програма видала повідомлення про помилку і зупинила свою роботу вона була б для нас марна. Існування NaN дає нам можливість повернути його в якості результату взяття квадратного кореня і продовжити роботу.

нескінченність

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

Арифметика з використанням інтуїтивна зрозуміла: при розподілі кінцевої величини на результат буде нулем; при додаванні або вирахуванні з кінцевої величини результат буде або відповідно.

Наведемо невеликий приклад нескінченної арифметики.

Припустимо, ми працюємо з функцією

Даний запис функції не дуже хороша. При sqrt \ beta ^ / 2> "/> sqrt \ beta ^ / 2>" /> в знаменнику буде викликано переповнення і результатом буде 0. Це некоректно, тому що повертається результатом повинна бути величина порядку. Перепишемо формулу в іншому вигляді.

Ця формула не буде так скоро викликати переповнення. У нулі вона також буде приймати коректне значення, так як "/> округлятиметься нулем.

Цей приклад показує основна перевага використання нескінченної арифметики: використання часто дозволяє обійти перевірки численних крайніх випадків.

Нуль зі знаком

Нуль відповідає нульовий мантисі і показником ступеня -1 "/>. Залежно від значення знакового біта може бути і. Обґрунтуємо введення цих спеціальних значень.

Для початку зробимо цікаве зауваження: в стандарті IEEE визначено, що. Це зроблено для того, щоб при умовних операторах виду не виникало невизначеності. Але це не означає, що стандарт не розрізняє двох цих значень. При множенні чисел на нулі зі знаками або при розподілі нулів зі знаками на числа знаки визначаються у відповідність зі звичайною знаковою арифметикою. Наприклад, і.

Припустимо, що у нуля не було б знака. Тоді при виникла б невизначеність з обчисленням значення виразу. Невизначеність полягає в тому, що і "/> і" /> брали б значення 0. У той же час брало б логічно вірне значення. Іншими словами,

З огляду на існування нескінченностей зі знаками єдино вірним рішенням даної проблеми є введення нулів зі знаками.

Наведемо ще один приклад.

Розглянемо функцію. Припустимо, що - дуже маленьке негативне число. Якби воно округляється нулем, то результатом би була, що, звичайно, неправильно. У стандарті IEEE не виникає такої проблеми. В цьому випадку округляється і повертається значення NaN.

ненормалізованние числа

Останнім спеціальним значенням стандарту IEEE є ненормалізованние числа.

Розглянемо приклад. Нехай, і = -98 "/>. Числа і - числа з плаваючою точкою, що відрізняються від мінімально представимо числа більше ніж в 10 разів. У цих чисел є цікава особливість. Їх різниця дорівнює нулю, хоча вони не рівні один одному. Це відбувається тому, що округляється нулем. нам би хотілося, щоб звичне нам тотожність

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

Введення ненормалізованих чисел вирішує цю проблему.

Суть полягає в тому, що при показнику ступеня рівному "/> мантиса не повинна бути нормализованной. Таким чином при, і = -98" /> вже не мінімально представимое число. також є коректним числом з плаваючою крапкою.

Доступ до формату в різних компіляторах

В папці include настановної директорії VC існує стандартний Хідер "float.h", в якому описані основні параметри форматів float, double і long double. Також існує Хідер "limits.h", в якому описаний ряд функцій по роботі зі спеціальними значеннями.

Borland C compiler (3.1)

У тій же папці include знаходиться Хідер "float.h"

GCC compiler (3.4)

В папці установки (usr / lib / gcc /.) Є все таже папка include з Хідер. У ній є файл "float.h".

Список літератури