Очікує на перевірку

Число з рухомою комою

Матеріал з Вікіпедії — вільної енциклопедії.
(Перенаправлено з Плаваюча кома)
Перейти до навігації Перейти до пошуку

Число́ з рухо́мою ко́мою[1][2][3] — форма подання дійсних чисел, в якій число зберігається у формі мантиси і показника степеня.

Число з рухомою комою має фіксовану відносну точність, залежну від кількості розрядів мантиси, і змінювану абсолютну. Найчастіше використовувані подання затверджено в стандарті IEEE 754. Реалізація математичних операцій з числами з рухомою комою у комп'ютерах може бути як апаратною, так і програмною.

Z3, один з перших електромеханічних програмованих комп'ютерів, використовував числа з рухомою комою (копія з Німецького музею в Мюнхені).

В обчислювальній техніці числа з рухомою комою (FP) — спосіб подання підмножини дійсних чисел за допомогою цілого числа з фіксованою точністю, яке називається мантисою, масштабованим за допомогою цілого показника фіксованої основи. Наприклад, 12,345 — це число з рухомою комою за основою десять із п’ятьма цифрами точності:

Однак, на відміну від 12.345, 12.3456 не є числом з рухомою комою за основою десять із п’ятьма цифрами точності — воно потребує шести цифр точності; найближче число з рухомою комою лише з п’яти цифр дорівнює 12,346. На практиці більшість систем з рухомою комою використовують основу два, хоча також поширена основа десять (десяткове число з рухомою комою).

Арифметичні операції з рухомою комою, такі як додавання та ділення, наближають відповідні арифметичні операції з дійсними числами шляхом округлення будь-якого результату, який сам по собі не є числом з рухомою комою, до найближчого числа з рухомою комою. Наприклад, в арифметиці з рухомою комою з точністю до п’яти десятих цифр суму 12,345 + 1,0001 = 13,3451 можна округлити до 13,345.

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

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

Протягом багатьох років у комп’ютерах використовували різноманітні подання чисел з рухомою комою. У 1985 році було створено стандарт IEEE 754 для арифметики з рухомою комою, і з 1990-х років найчастіше зустрічаються представлення, визначені IEEE.

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

Блок з рухомою комою (FPU, розмовно - математичний співпроцесор) — це частина комп’ютерної системи, спеціально розроблена для виконання операцій над числами з рухомою комою.

Огляд

[ред. | ред. код]

Числа з рухомою комою

[ред. | ред. код]

Представлення числа визначає певний спосіб кодування числа, зазвичай у вигляді рядка цифр.

Існує кілька механізмів, за допомогою яких рядки цифр можуть представляти числа. У стандартній математичній нотації рядок цифр може мати будь-яку довжину, а розташування коми основи вказується шляхом розміщення там явного символу «крапка» (крапка або кома). Якщо кому основи не вказано, то рядок неявно представляє ціле число, а невказана кома основи буде розташована з правого кінця рядка, поруч із молодшою цифрою. У системах із фіксованою комою позиція в рядку вказується для коми основи. Таким чином, у схемі з фіксованою комою може використовуватися рядок із 8 десяткових цифр із десятковою крапкою посередині, де "00012345" представлятиме 0001,2345.

У науковій нотації дане число масштабується за степенями 10, так що воно лежить у певному діапазоні — як правило, між 1 і 10, при цьому кома в основі з’являється відразу після першої цифри. Як степінь десяти, коефіцієнт масштабування вказується окремо в кінці числа. Наприклад, орбітальний період супутника Юпітера Іо становить 152 853,5047 секунд, значення, яке буде представлено в стандартній формі наукового запису як 1,528535047 × 105 секунд.

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

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

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

Використовуючи основу 10 (відомий десятковий запис) як приклад, число 152 853,5047, що має десять десяткових цифр точності, представлено як мантиса 1 528 535 047 разом із показником 5. Щоб визначити фактичне значення, після першої цифри мантиси ставлять десяткову кому і результат множать на 105 , тобто 1,528535047 × 105, або 152 853,5047. При збереженні такого числа не потрібно зберігати основу (10), оскільки вона буде однаковою для всього діапазону підтримуваних чисел і, таким чином, може бути виведена.

Символічно це записується так: де s — мантиса (без урахування будь-якої неявної десяткової коми), p — точність (кількість цифр у мантисі), b — основа (у нашому прикладі це число десять), а e — експонента(порядок).

Історично склалося так, що кілька основ числення використовувалися для представлення чисел з рухомою комою, причому основа два (двійкова) є найпоширенішою, за нею йде основа десять (десяткова з рухомою комою) та інші менш поширені різновиди, такі як основа шістнадцять (шістнадцяткова з рухомою комою ), основа вісім (вісімкове число з рухомою комою ), основа чотири (четвертинне число з рухомою комою ), основа три (збалансована трійка з рухомою комою ) і парна основа 256 і основа 65 536.

Число з рухомою комою є раціональним числом, оскільки воно може бути представлене як одне ціле число, поділене на інше; наприклад1,45 × 103 це (145/100) × 1000 або 145 000 /100. Основа визначає дроби, які можна представити; наприклад, 1/5 не можна точно представити як число з рухомою комою за допомогою двійкової системи, але 1/5 можна точно представити за допомогою десяткової системи (0,2 або2 × 10−1). Однак 1/3 не може бути точно представлена ні двійковою (0,010101...), ні десятковою (0,333...), але в основі 3 це тривіально (0,1 або 1×3−1). Випадки, коли відбуваються нескінченні розширення, залежать від основи та її простих множників.

Спосіб, у який мантиса (включаючи її знак) і експоненту зберігаються в комп’ютері, залежить від реалізації. Загальні формати IEEE детально описані пізніше та в інших місцях, але як приклад у двійковому представленні з рухомою комою одинарної точності (32 біта), , отже, мантисою є рядок із 24 бітів. Наприклад, перші 33 біти числа π : У цьому двійковому розширенні позначимо позиції від 0 (крайній лівий біт або старший біт) до 32 (крайній правий біт). 24-розрядна мантиса зупинятиметься на позиції 23, показаній як підкреслений біт0 вище. Наступний біт, у позиції 24, називається бітом округлення. Він використовується для округлення 33-бітного наближення до найближчого 24-бітного числа (існують спеціальні правила для половинних значень, але тут не так). Цей біт, який є 1 у цьому прикладі додається до цілого числа, утвореного крайніми лівими 24 бітами, що дає: Коли це зберігається в пам’яті за допомогою кодування IEEE 754, це стає мантисою. Передбачається, що мантиса має двійкову кому праворуч від крайнього лівого біта. Отже, двійкове представлення π обчислюється зліва направо наступним чином: де p – точність (24 у цьому прикладі), n - це позиція біта мантиси зліва (починаючи з0 і закінчуючи о23 тут), а e — показник степеня (1 у цьому прикладі).

Можна вимагати, щоб старша цифра мантиси ненульового числа була відмінною від нуля (за винятком випадків, коли відповідний показник степеня буде меншим за мінімальний). Цей процес називається нормалізацією. Для двійкових форматів (у яких використовуються лише цифри0 і1), ця ненульова цифра є обов’язковою1. Таким чином, його не потрібно представляти в пам’яті, дозволяючи формату мати ще один біт точності. Це правило по-різному називається угодою про провідні біти, неявною угодою про біти, угодою про приховані біти або угодою про передбачувані біти.

Альтернативи числам з рухомою комою

[ред. | ред. код]

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

  • Представлення з фіксованою комою використовує цілочисельні апаратні операції, керовані програмною реалізацією певної угоди про розташування двійкової або десяткової коми, наприклад, 6 біт або цифр справа. Апаратне забезпечення для маніпулювання цими представленнями є менш дорогим, ніж з рухомою комою, і його також можна використовувати для виконання звичайних цілочисельних операцій. Двійкова фіксована кома зазвичай використовується в програмах спеціального призначення на вбудованих процесорах, які можуть виконувати лише цілочисельну арифметику, але фіксована кома в десятковому вигляді поширена в комерційних програмах.
  • Логарифмічні системи числення (LNS) представляють дійсне число логарифмом його абсолютного значення та знакового біта. Розподіл значень подібний до числа з рухомою комою, але крива від значення до представлення (тобто графік функції логарифма) є плавною (за винятком 0). На відміну від арифметики з рухомою комою, у логарифмічній системі числення множення, ділення та піднесення до степеня є простими для реалізації, але додавання та віднімання є складними. (Симетрична) арифметика рівня індексу (LI та SLI) Чарльза Кленшоу, Френка Олвера та Пітера Тернера є схемою, заснованою на узагальненому логарифмічному представленні.
  • Конічне представлення з рухомою комою, яке, здається, не використовується на практиці.
  • Деякі прості раціональні числа (наприклад, 1/3 і 1/10) не можуть бути точно представлені у двійковій формі з рухомою комою, незалежно від точності. Використання іншої основи дозволяє відобразити деякі з них (наприклад, 1/10 у десятковій комі з рухомою комою), але можливості залишаються обмеженими. Програмні пакети, які виконують раціональну арифметику, представляють числа у вигляді дробів із цілим чисельником і знаменником, і тому можуть точно представляти будь-яке раціональне число. Такі пакети, як правило, повинні використовувати арифметику "bignum" для окремих цілих чисел.
  • Інтервальна арифметика дозволяє представляти числа у вигляді інтервалів і отримувати гарантовані межі результатів. Зазвичай він базується на іншій арифметиці, зокрема з рухомою комою.
  • Системи комп’ютерної алгебри, такі як Mathematica, Maxima та Maple, часто можуть обробляти ірраціональні числа, наприклад або цілком «формальним» способом (символьне обчислення), не маючи справу з конкретним кодуванням мантиси. Така програма може обчислювати такі вирази, як "" саме тому, оскільки він запрограмований на обробку основної математики безпосередньо, замість використання приблизних значень для кожного проміжного обчислення.

Історія

[ред. | ред. код]
Леонардо Торрес Кеведо, 1914 року опублікував роботу щодо використання чисел з рухомою комою в "Аналітичній машині"

У 1914 році іспанський інженер Леонардо Торрес Кеведо опублікував «Нариси з автоматики», де він розробив спеціальний електромеханічний калькулятор на основі аналітичної машини Чарльза Беббіджа та описав спосіб узгодженого зберігання чисел з рухомою комою. Він заявив, що числа будуть зберігатися в експоненціальному форматі n x 10, і запропонував три правила, за якими машини можуть реалізовувати послідовне маніпулювання числами з рухомою комою. Для Торреса « n завжди матиме однакову кількість цифр (наприклад, шість), перша цифра n матиме порядок десятих, друга — сотих тощо, і кожну кількість записуватимемо у формі: n ; m." Формат, який він запропонував, показує потребу в значенні фіксованого розміру, який зараз використовується для даних з рухомою комою, фіксації розташування десяткової крапки в значенні, щоб кожне представлення було унікальним, і як форматувати такі числа, вказавши синтаксис які можна було ввести через друкарську машинку, як це було у випадку з його електромеханічним арифмометром у 1920 році.

Конрад Цузе, розробник комп’ютера Z3, який використовував 22-розрядне двійкове представлення чисел з рухомою комою

У 1938 році Конрад Цузе з Берліна створив Z1, перший двійковий, програмований механічний комп'ютер, він використовував 24-бітне двійкове представлення чисел з рухомою комою з 7-бітним порядком зі знаком, 17-бітною мантисою (включаючи один неявний біт) і бітом знака. Більш надійний Z3 на основі реле, був завершений у 1941 році, мав представлення як для додатньої, так і для від'ємної нескінченності; зокрема, він реалізує визначені операції з нескінченністю, такі як , і він зупиняється на невизначених операціях, таких як .

Цузе також запропонував, але не завершив, ретельно округлену арифметику з рухомою комою, яка включає і представлення NaN, випереджаючи особливості стандарту IEEE на чотири десятиліття. Навпаки, фон Нейман рекомендував не використовувати числа з рухомою комою для машини IAS 1951 року, стверджуючи, що арифметика з фіксованою комою є кращою.

Першим комерційним комп'ютером з апаратним забезпеченням для операцій з рухомою комою був комп'ютер Z4 Zuse, розроблений у 1942–1945 роках. У 1946 році Bell Laboratories представила модель V, яка реалізувала десяткові числа з рухомою комою.

Комп'ютер Pilot ACE мав двійкову арифметику з рухомою комою, і він почав працювати в 1950 році в Національній фізичній лабораторії Великобританії. Пізніше тридцять три машини були комерційно продані як English Electric DEUCE. Арифметика фактично реалізована в програмному забезпеченні, але з тактовою частотою в один мегагерц швидкість операцій з рухомою та фіксованою комою в цій машині спочатку була вищою, ніж у багатьох конкуруючих комп’ютерів.

Масове виробництво IBM 704 розпочалося в 1954 році; він запровадив використання зміщеного показника степеня. Протягом багатьох десятиліть після цього апаратне забезпечення з рухомою комою було, як правило, додатковою функцією, а комп’ютери, які його мали, називали «науковими комп’ютерами» або такими, що мали можливість «наукових обчислень» (SC). Лише після випуску Intel i486 у 1989 році персональні комп’ютери загального призначення мали апаратне забезпечення з рухомою комою як стандартну функцію.

Серія UNIVAC 1100/2200, представлена в 1962 році, підтримувала два представлення з рухомою комою:

  • Одинарна точність : 36 біт, організованих як 1-бітовий знак, 8-бітний порядок і 27-бітна мантиса.
  • Подвійна точність : 72 біти, організовані як 1-бітний знак, 11-бітний порядок і 60-бітова мантиса.

IBM 7094, також представлений у 1962 році, підтримував представлення одинарної та подвійної точності, але не мав відношення до представлень UNIVAC. Дійсно, у 1964 році IBM представила шістнадцяткове представлення з рухомою комою у своїх мейнфреймах System/360 ; ці ж представлення все ще доступні для використання в сучасних системах z/Architecture. У 1998 році IBM реалізувала IEEE-сумісну двійкову арифметику з рухомою комою у своїх мейнфреймах; у 2005 році IBM також додала сумісну з IEEE десяткову арифметику з рухомою комою.

Спочатку комп’ютери використовували багато різних представлень для чисел з рухомою комою. Відсутність стандартизації на рівні мейнфреймів була постійною проблемою на початку 1970-х років для тих, хто писав і підтримував вихідний код вищого рівня; ці стандарти виробників із рухомою комою відрізнялися розмірами слів, представленнями, поведінкою округлення та загальною точністю операцій. Сумісність із рухомою комою в багатьох обчислювальних системах відчайдушно потребувала стандартизації на початку 1980-х років, що призвело до створення стандарту IEEE 754, коли слово 32-bit (або 64-bit) стало звичним. Цей стандарт значною мірою ґрунтувався на пропозиції Intel, яка розробляла матемтичний співпроцесор i8087; Motorola, яка приблизно в той же час розробляла 68000, також внесла значний внесок.

У 1989 році математик і інформатик Вільям Кахан був удостоєний премії Тюрінга за те, що він був головним архітектором цієї пропозиції; йому допомагали його учень Джером Кунен і запрошений професор Гарольд Стоун.

Серед нововведень x86 такі:

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

Діапазон чисел з рухомою комою

[ред. | ред. код]

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

У типовій комп’ютерній системі двійкове число з рухомою комою подвійної точності (64-розрядне) має коефіцієнт 53 біти (включаючи 1 неявний біт), експоненту 11 бітів і 1 знаковий біт. Оскільки 2 10 = 1024, повний діапазон додатних нормальних чисел з рухомою комою в цьому форматі становить від 2 −1022  ≈ 2 × 10 −308 до приблизно 2 1024  ≈ 2 × 10 308.

Кількість нормальних чисел з рухомою комою в системі (B, P, L, U), де

  • B — основа системи,
  • P — точність мантиси (за основою B),
  • L – найменший показник системи,
  • U — найбільший показник системи,

є ..

Існує найменше додатне нормальне число з рухомою комою,

Нижній рівень = UFL = , ,

яка має 1 як початкову цифру та 0 для решти цифр мантиси, і найменше можливе значення для експоненти.

Є найбільше число з рухомою комою,

Рівень переповнення = OFL = , ,

який має B − 1 як значення для кожної цифри мантиси і найбільше можливе значення для експоненти.

Крім того, існують репрезентовані значення строго між −UFL і UFL. А саме позитивні та негативні нулі, а також субнормальні числа.

IEEE 754: числа з рухомою комою в сучасних комп’ютерах

[ред. | ред. код]

Основна стаття: IEEE 754

IEEE стандартизував комп’ютерне представлення двійкових чисел з рухомою комою в IEEE 754 (він же IEC 60559) у 1985 році. Цього першого стандарту дотримуються майже всі сучасні машини. Його було переглянуто в 2008 році. Мейнфрейми IBM підтримують власний шістнадцятковий формат з рухомою комою IBM і десятковий формат з рухомою комою IEEE 754-2008 на додаток до двійкового формату IEEE 754. Серія Cray T90 мала версію IEEE, але SV1 все ще використовує формат Cray з рухомою комою.

Стандарт передбачає багато тісно пов'язаних форматів, що відрізняються лише декількома деталями. П'ять із цих форматів називаються базовими форматами, а інші — форматами розширеної точності та форматом розширеної точності. Три формати особливо широко використовуються в комп’ютерному обладнанні та мовах: [ потрібна цитата ]

  • Одинарна точність (binary32), зазвичай використовується для представлення типу "float" у родині мов C. Це двійковий формат, який займає 32 біти (4 байти), а його символ має точність 24 біти (приблизно 7 десяткових цифр).
  • Подвійна точність (binary64), зазвичай використовується для представлення типу "double" у родині мов C. Це двійковий формат, який займає 64 біти (8 байтів) і має точність 53 біти (приблизно 16 десяткових цифр).
  • Подвійний розширений формат, який також неоднозначно називають форматом "розширеної точності". Це двійковий формат, який займає щонайменше 79 бітів (80, якщо не використовується правило прихованих/неявних бітів), а його мантиса має точність щонайменше 64 біти (приблизно 19 десяткових цифр). Стандарти C99 і C11 сімейства мов C у своєму додатку F ("IEC 60559 арифметика з рухомою комою") рекомендують надавати такий розширений формат як " long double ". Архітектура x86 забезпечує формат, що задовольняє мінімальні вимоги (64-бітна мантиса, 15-бітний експонентний показник, що відповідає 80 бітам). Часто на таких процесорах цей формат можна використовувати з "long double", хоча розширена точність недоступна з MSVC. Для цілей вирівнювання багато інструментів зберігають це 80-бітове значення в 96- або 128-бітному просторі. На інших процесорах «довга подвійна» може означати більший формат, такий як почетверна точність, або просто подвійна точність, якщо будь-яка форма розширеної точності недоступна.

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

  • Формати з рухомою комою Decimal64 і decimal128. Ці формати (особливо decimal128) широко поширені у фінансових операціях, оскільки разом із форматом decimal32 вони дозволяють правильно округляти десяткове число.
  • Четверна точність (двійковий 128). Це двійковий формат, який займає 128 біт (16 байт) і має точність 113 біт (приблизно 34 десяткові цифри).
  • Половина точності, також називається binary16, 16-бітне значення з рухомою комою. Він використовується в графічній мові NVIDIA Cg і в стандарті openEXR.

Будь-яке ціле число з абсолютним значенням менше 2 24 може бути точно представлено у форматі одинарної точності, а будь-яке ціле число з абсолютним значенням менше 2 53 може бути точно представлено у форматі подвійної точності. Крім того, можна представити широкий діапазон степенів, що вдвічі більше такого числа. Ці властивості іноді використовуються для чисто цілих даних, щоб отримати 53-розрядні цілі на платформах, які мають подвійну точність з рухомою комою, але лише 32-розрядні цілі.

Стандарт визначає деякі спеціальні значення та їх представлення: позитивна нескінченність (+∞), негативна нескінченність (−∞), негативний нуль (−0), відмінний від звичайного («позитивного») нуля, і значення «не числа» (NaN).

Порівняння чисел з рухомою комою, як визначено стандартом IEEE, дещо відрізняється від звичайного цілочисельного порівняння. Від’ємний і додатний нулі порівнюються, а кожен NaN не дорівнює кожному значенню, включаючи себе. Усі скінченні числа з рухомою комою строго менші за +∞ і строго більші за −∞, і вони впорядковані так само, як і їхні значення (у наборі дійсних чисел).

Внутрішнє подання

[ред. | ред. код]

Числа з рухомою комою зазвичай упаковуються в дані комп’ютера як біт знака, поле експоненти та мантиса зліва направо. Для двійкових форматів IEEE 754 (базового та розширеного), які мають існуючі апаратні реалізації, вони розподіляються таким чином:

Тип Кількість бітів Зсув експоненти Точність бітів Кількість

десяткових цифр

Знак Порядок Мантиса Разом
половинна (IEEE 754-2008) 1 5 10 16 15 11 ~3.3
одинарна 1 8 23 32 127 24 ~7.2
подвійна 1 11 52 64 1023 53 ~15.9
розширена точність x86 1 15 64 80 16383 64 ~19.2
четверна 1 15 112 128 16383 113 ~34,0

Хоча експонента може бути додатною або від’ємною, у двійкових форматах вона зберігається як число без знаку, до якого додається фіксоване «зміщення». Значення всіх нулів у цьому полі зарезервовані для нулів і субнормальних чисел ; значення всіх одиниць зарезервовані для нескінченностей і NaN. Діапазон експонент для звичайних чисел становить [−126, 127] для одинарної точності, [−1022, 1023] для подвійної або [−16382, 16383] для квадратичної. Нормальні числа виключають субнормальні значення, нулі, нескінченності та NaN.

У двійкових форматах обміну IEEE початковий 1 біт нормалізованої мантиси фактично не зберігається в даних комп’ютера. Його називають «прихованим» або «неявним» бітом. Через це формат одинарної точності фактично має значущу точність із 24 бітами, формат подвійної точності має 53, а формат quad має 113.

Наприклад, було показано вище, що π, округлене до 24 біт з точністю, має:

  • знак = 0; e = 1; s = 110010010000111111011011 (включаючи прихований біт)

Сума зміщення експоненти (127) і експоненти (1) дорівнює 128, тому це представлено у форматі одинарної точності як

  • 0 10000000 10010010000111111011011 (за винятком прихованого біта) = 40490FDB як шістнадцяткове число.

Приклад макета для 32-розрядного числа з рухомою комою

і 64-розрядна ("подвійна") розкладка схожа.

Інші відомі формати з рухомою комою

[ред. | ред. код]

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

  • Microsoft Binary Format (MBF) був розроблений для мовних продуктів Microsoft BASIC, включаючи перший продукт Microsoft Altair BASIC (1975), TRS-80 LEVEL II, MBASIC CP/M, BASICA IBM PC 5150, MS- DOS GW -BASIC і QuickBASIC до версії 4.00. QuickBASIC версії 4.00 і 4.50 перейшли на формат IEEE 754-1985, але можуть повернутися до формату MBF за допомогою параметра команди /MBF. MBF був розроблений і розроблений на симульованому Intel 8080 Монте Давідоффом, колегою Білла Гейтса, навесні 1975 року для MITS Altair 8800. Початковий випуск у липні 1975 року підтримував формат одинарної точності (32 біти) через вартість 4-кілобайтної пам’яті MITS Altair 8800. У грудні 1975 року 8-кілобайтна версія додала формат подвійної точності (64 біти). Варіант формату з одинарною точністю (40 біт) був прийнятий для інших процесорів, зокрема для MOS 6502 (Apple //, Commodore PET, Atari), Motorola 6800 (MITS Altair 680) і Motorola 6809 (кольоровий комп’ютер TRS-80). Усі мовні продукти Microsoft з 1975 по 1987 роки використовували двійковий формат Microsoft, доки Microsoft не прийняла стандартний формат IEEE-754 у всіх своїх продуктах, починаючи з 1988 року до їхніх поточних випусків. MBF складається з формату MBF одинарної точності (32 біти, «6-розрядний BASIC»), формат MBF розширеної точності (40 біт, «9-розрядний BASIC»), і формат MBF подвійної точності (64 біти); кожен з них представлений 8-бітним експонентою, за яким йде знаковий біт, за яким слідує мантиса відповідно 23, 31 і 55 біт.
  • Формат Bfloat16 потребує такого ж об’єму пам’яті (16 біт), що й формат напівточності IEEE 754, але експоненті виділяє 8 біт замість 5, таким чином забезпечуючи той самий діапазон, що й число одинарної точності IEEE 754. Компромісом є знижена точність, оскільки завершальне значуще поле зменшено з 10 до 7 біт. Цей формат в основному використовується при навчанні моделей машинного навчання, де діапазон є більш цінним, ніж точність. Багато прискорювачів машинного навчання забезпечують апаратну підтримку цього формату.
  • Формат TensorFloat-32 поєднує 8 біт експоненти Bfloat16 з 10 бітами кінцевого значущого поля форматів напівточності, що призводить до розміру 19 біт. Цей формат був представлений компанією Nvidia, яка забезпечує його апаратну підтримку в тензорних ядрах своїх графічних процесорів на основі архітектури Nvidia Ampere. Недоліком цього формату є його розмір, який не є степенем 2. Однак, згідно з Nvidia, цей формат має використовуватися апаратним забезпеченням лише внутрішньо для прискорення обчислень, тоді як вхідні та вихідні дані мають зберігатися в 32-розрядному єдиному файлі. -точний формат IEEE 754.
  • Графічні процесори з архітектурою Hopper забезпечують два формати FP8: один із таким же числовим діапазоном, як напівточність (E5M2), і інший із вищою точністю, але меншим діапазоном (E4M3).
Bfloat16, TensorFloat-32 і два формати FP8 порівняно з форматами напівточності та одинарної точності IEEE 754
Тип Знак Експонента Кінцеве значуще поле Всього біт
FP8 (E4M3) 1 4 3 8
FP8 (E5M2) 1 5 2 8
Напівточність 1 5 10 16
Bfloat16 1 8 7 16
TensorFloat-32 1 8 10 19
Одинарна точність 1 8 23 32

Представлені числа, перетворення та округлення

[ред. | ред. код]

За своєю природою всі числа, виражені у форматі з рухомою комою, є раціональними числами з кінцевим розкладанням за відповідною основою (наприклад, кінцевим десятковим розкладанням за основою 10 або кінцевим двійковим розкладанням за основою 2). Ірраціональні числа, такі як π або √2, або некінцеві раціональні числа, повинні бути апроксимовані. Кількість цифр (або бітів) точності також обмежує набір раціональних чисел, які можуть бути представлені точно. Наприклад, десяткове число 123456789 не може бути точно представлено, якщо доступні лише вісім десяткових цифр точності (воно буде округлено до одного з двох значень, які можна представити, 12345678 × 101 або 12345679 × 101), те ж саме стосується не кінцевих цифр (.5 округляються до .55555555 або .55555556).

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

Чи має раціональне число кінцеве розширення, залежить від основи. Наприклад, за основою 10 число 1/2 має закінчення (0,5), тоді як число 1/3 не має (0,333...). За основою 2 завершуються лише раціональні числа зі знаменниками, які є степенями 2 (наприклад, 1/2 або 3/16). Будь-яке раціональне число зі знаменником, який має простий множник, відмінний від 2, матиме нескінченне двійкове розкладання. Це означає, що числа, які здаються короткими та точними, коли записуються в десятковому форматі, можуть потребувати наближення під час перетворення у двійкові числа з рухомою комою. Наприклад, десяткове число 0,1 не можна представити у двійковій формі з рухомою комою будь-якої кінцевої точності; точне двійкове представлення матиме послідовність «1100», яка продовжується нескінченно:

e = −4; s = 1100110011001100110011001100110011...,

де, як і раніше, s — мантиса, а e — показник степеня.

При округленні до 24 бітів це стає

e = −4; s = 110011001100110011001101,

що насправді дорівнює 0,100000001490116119384765625 у десятковій системі.

Як наступний приклад, дійсне число π, представлене у двійковій системі у вигляді нескінченної послідовності бітів, є

11,0010010000111111011010101000100010000101101000110000100011010011...

але є

11,0010010000111111011011

при наближенні округленням до 24 бітів.

У двійковій формі з рухомою комою одинарної точності це представлено як s  = 1,10010010000111111011011 з e  = 1. Це має десяткове значення

3,141592 7410125732421875,

тоді як точніше наближення справжнього значення π є

3,14159265358979323846264338327950 ...

Результат округлення відрізняється від справжнього значення приблизно на 0,03 частини на мільйон і збігається з десятковим представленням числа π у перших 7 цифрах. Різниця полягає в похибці дискретизації і обмежена епсилоном машини.

Арифметична різниця між двома послідовними числами з рухомою комою, які можна представити й мають однаковий показник, називається одиницею на останньому місці (ULP). Наприклад, якщо між представленими числами 1,45a70c22 hex і 1,45a70c24 hex немає числа, яке можна представити, ULP дорівнює 2×16 −8 або 2 −31. Для чисел із частиною експоненти за основою 2, яка дорівнює 0, тобто чисел із абсолютним значенням, вищим або рівним 1, але меншим за 2, ULP дорівнює рівно 2 −23 або приблизно 10 −7 з одиничною точністю, і точно 2 −53 або приблизно 10 −16 у подвійній точності. Обов’язкова поведінка обладнання, сумісного з IEEE, полягає в тому, щоб результат був у межах половини ULP.

Режими округлення

[ред. | ред. код]

Округлення використовується, коли точний результат операції з рухомою комою (або перетворення у формат із рухомою комою) потребує більше цифр, ніж цифр у мантисі. IEEE 754 вимагає правильного округлення : тобто округлений результат виглядає так, ніби для обчислення значення було використано нескінченно точну арифметику, а потім округлено (хоча в реалізації для забезпечення цього потрібні лише три додаткові біти). Існує кілька різних схем округлення (або режимів округлення). Історично типовим підходом було скорочення. З моменту введення IEEE 754 метод за замовчуванням (округлення до найближчого, прив’язка до парного, іноді званий банківським округленням) використовується частіше. Цей метод округлює ідеальний (нескінченно точний) результат арифметичної операції до найближчого значення, яке можна представити, і дає це представлення як результат. У разі рівності вибирається значення, за якого мантиса закінчується парною цифрою. Стандарт IEEE 754 вимагає застосування однакового округлення до всіх основних алгебраїчних операцій, включаючи квадратний корінь і перетворення, коли є числовий результат (не NaN). Це означає, що результати операцій IEEE 754 повністю визначені у всіх бітах результату, за винятком представлення NaN. (Функції «Бібліотеки», такі як косинус і логарифм, не є обов’язковими.)

Також доступні альтернативні варіанти округлення. IEEE 754 визначає такі режими округлення:

  • округлення до найближчого, де прив’язує округлення до найближчої парної цифри в необхідній позиції (за замовчуванням і на сьогоднішній день найпоширеніший режим)
  • округлення до найближчого, де округлення від нуля (необов’язковий для двійкового числа з рухомою комою та зазвичай використовується в десятковому)
  • округлення в більшу сторону (до +∞; негативні результати, таким чином, округлення до нуля)
  • округлити вниз (у бік −∞; негативні результати, таким чином, округлити від нуля)
  • округлення до нуля (усічення; це подібно до звичайної поведінки перетворень з рухомою комою в ціле число, які перетворюють −3,9 у −3 і 3,9 у 3)

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

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

[ред. | ред. код]

Перетворення двійкового числа з рухомою комою подвійної точності в десятковий рядок є звичайною операцією, але алгоритм, який дає водночас точні та мінімальні результати, не з’явився у друку до 1990 року, коли Стіл і Вайт випустили Dragon4. Деякі з покращень з тих пір включають:

  • dtoa.c Девіда М. Гея, практична реалізація багатьох ідей у Dragon4 з відкритим кодом.
  • Grisu3 із 4-кратним прискоренням, оскільки він усуває використання bignums. Необхідно використовувати з резервним варіантом, оскільки він не працює приблизно в 0,5% випадків.
  • Errol3, завжди успішний алгоритм, подібний до Grisu3, але повільніший за нього. Мабуть, не так добре, як Грізу з достроковим припиненням із запасним ударом.
  • Ryū, завжди успішний алгоритм, швидший і простіший за Grisu3.
  • Schubfach, завжди успішний алгоритм, який базується на подібній ідеї до Ryū, розроблений майже одночасно та незалежно. У певних тестах працює краще, ніж Ryū та Grisu3.

Багато сучасних мовних середовищ виконання використовують Grisu3 із резервним Dragon4.

Перетворення десяткової системи в двійкову

[ред. | ред. код]

Проблема розбору десяткового рядка в двійкове представлення FP є складною, точний синтаксичний аналізатор не з’явився до роботи Клінгера 1990 року (реалізовано в dtoa.c). Подальша робота також просувалась у напрямку швидшого аналізу.

Операції з рухомою комою

[ред. | ред. код]

Для зручності представлення та розуміння в прикладах буде використано десяткове число з точністю до 7 цифр, як у форматі IEEE 754 decimal32. Фундаментальні принципи однакові в будь-якому розрахунку чи точності, за винятком того, що нормалізація необов’язкова (вона не впливає на числове значення результату). Тут s позначає мантису, а e позначає показник степеня.

Додавання і віднімання

[ред. | ред. код]

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

  123456,7 = 1,234567 × 10^5
  101,7654 = 1,017654 × 10^2 = 0,001017654 × 10^5
  Отже:
  123456,7 + 101,7654 = (1,234567 × 10^5) + (1,017654 × 10^2)
                      = (1,234567 × 10^5) + (0,001017654 × 10^5)
                      = (1,234567 + 0,001017654) × 10^5
                      = 1,235584654 × 10^5

Детально:

  e=5; s=1,234567 (123456,7)
+ e=2; s=1,017654 (101,7654)
  e=5; s=1,234567
+ e=5; s=0,001017654 (після зсуву)
--------------------
  e=5; s=1,235584654 (дійсна сума: 123558,4654)

Це справжній результат, точна сума операндів. Його буде округлено до семи цифр, а потім нормалізовано, якщо необхідно. Кінцевий результат є

  e=5; s=1,235585 (кінцева сума: 123558,5)

Наймолодші три цифри другого операнда (654) по суті втрачаються. Це помилка округлення. У крайньому випадку сума двох ненульових чисел може дорівнювати одному з них:

  e=5; s=1,234567
+ e=−3; s=9,876543
  e=5; s=1,234567
+ e=5; s=0,00000009876543 (після зсуву)
----------------------
  e=5; s=1,23456709876543 (справжня сума)
  e=5; s=1,234567 (після округлення та нормалізації)

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

Інша проблема втрати значущості виникає, коли віднімаються наближення до двох майже рівних чисел. У наступному прикладі e  = 5; s  = 1,234571 і e  = 5; s  = 1,234567 є наближеними значеннями раціональних чисел 123457,1467 і 123456,659.

  e=5; s=1,234571
− e=5; s=1,234567
----------------
  e=5; s=0,000004
  e=−1; s=4,000000 (після округлення та нормалізації)

Різниця з рухомою комою обчислюється точно, тому що числа близькі — лема Штербенза гарантує це, навіть у випадку недоповнення, коли підтримується поступове недоповнення. Незважаючи на це, різниця вихідних чисел e  = −1; s  = 4,877000, що більш ніж на 20% відрізняється від різниці e  = −1; s  = 4,000000 наближень. У крайніх випадках усі значущі цифри точності можуть бути втрачені. Це скасування ілюструє небезпеку припущення, що всі цифри обчисленого результату є значущими. Робота з наслідками цих помилок є темою числового аналізу ; див. також проблеми з точністю.

Множення і ділення

[ред. | ред. код]

Для множення значущі множаться, а показники додаються, а результат округлюється та нормалізується.

  e=3; s=4,734612
× e=5; s=5,417242
-----------------------
  e=8; s=25,648538980104 (справжній продукт)
  e=8; s=25,64854 (після округлення)
  e=9; s=2,564854 (після нормалізації)

Подібним чином ділення виконується шляхом віднімання показника степеня дільника від показника степеня діленого та ділення значущого діленного на значуще дільника.

Немає проблем зі скасуванням або поглинанням при множенні або діленні, хоча невеликі помилки можуть накопичуватися під час послідовного виконання операцій. На практиці спосіб виконання цих операцій у цифровій логіці може бути досить складним (див. Алгоритм множення Бута та Алгоритм ділення). Щоб отримати швидкий і простий метод, перегляньте метод Горнера.

Літеральний синтаксис

[ред. | ред. код]

Літерали для чисел з рухомою комою залежать від мов. Вони зазвичай використовують eабо Eдля позначення наукової нотації. Мова програмування C і стандарт IEEE 754 також визначають синтаксис шістнадцяткового літералу з експонентою за основою 2 замість 10. У таких мовах, як C, коли десятковий експонент пропускається, десяткова кома необхідна, щоб відрізнити їх від цілих чисел. Інші мови не мають цілочисельного типу (наприклад, JavaScript) або допускають перевантаження числових типів (наприклад, Haskell). У цих випадках цифрові рядки, такі як, 123також можуть бути літералами з рухомою комою.

Приклади літералів із рухомою комою:

  • 99.9
  • -5000.12
  • 6.02e23
  • -3e-45
  • 0x1.fffffep+127у C та IEEE 754

Робота з винятковими випадками

[ред. | ред. код]

Додаткова інформація: IEEE 754 § Обробка винятків

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

  • Операція може бути математично невизначеною, як-от ∞/∞ або ділення на нуль.
  • Операція може бути допустимою в принципі, але не підтримуватися певним форматом, наприклад, обчислення квадратного кореня з −1 або аверссинуса з 2 (обидва з яких призводять до комплексних чисел).
  • Операція може бути допустимою в принципі, але результат може бути неможливим для представлення у вказаному форматі, оскільки експонента занадто велика або занадто мала для кодування в полі експоненти. Така подія називається переповненням (експонента надто велика), underflow (експонента надто мала) або деноралізацією (втрата точності).

До стандарту IEEE такі умови зазвичай спричиняли завершення програми або запускали якусь пастку, яку програміст міг зловити. Те, як це працювало, залежало від системи, тобто програми з рухомою комою не були переносними. (Термін «виняток», який використовується в IEEE 754, є загальним терміном, що означає виняткову умову, яка не обов’язково є помилкою, і є іншим використанням, ніж зазвичай визначене в мовах програмування, таких як C++ або Java, у яких « винятком " є альтернативний потік керування, ближче до того, що називається "пастка" в термінології IEEE 754.)

Тут обговорюється необхідний стандартний метод обробки винятків відповідно до IEEE 754 (додаткове перехоплення IEEE 754 та інші режими «альтернативної обробки винятків» не обговорюються). Арифметичні винятки (за замовчуванням) повинні бути записані в "липких" бітах прапора стану. Те, що вони «липкі», означає, що вони не скидаються наступною (арифметичною) операцією, а залишаються встановленими до явного скидання. Таким чином, використання «липких» прапорів дозволяє відкласти тестування виняткових умов до завершення повного виразу з рухомою комою або підпрограми: без них виняткові умови, які інакше не можна було б проігнорувати, вимагали б явного тестування відразу після кожної операції з рухомою комою. За замовчуванням операція завжди повертає результат відповідно до специфікації без переривання обчислення. Наприклад, 1/0 повертає +∞, а також встановлює біт прапора ділення на нуль (це значення за замовчуванням ∞ призначене для того, щоб часто повертати кінцевий результат під час використання в наступних операціях, тому його безпечно ігнорувати).

Оригінальний стандарт IEEE 754, однак, не рекомендував операції для обробки таких наборів бітів арифметичних винятків. Отже, хоча вони були реалізовані в апаратному забезпеченні, початкові реалізації мови програмування зазвичай не надавали засобів доступу до них (крім асемблера). З часом деякі стандарти мов програмування (наприклад, C99 /C11 і Fortran) були оновлені, щоб визначити методи доступу та зміни бітів прапора стану. Версія стандарту IEEE 754 2008 року тепер визначає кілька операцій для доступу та обробки бітів арифметичних прапорів. Модель програмування базується на одному потоці виконання, і використання їх декількома потоками має оброблятися засобами, що не входять до стандарту (наприклад, C11 вказує, що прапори мають локальне зберігання потоків).

IEEE 754 визначає п’ять арифметичних винятків, які мають бути записані в прапори стану («липкі біти»):

  • inexact, встановлюється, якщо округлене (і повернуте) значення відрізняється від математично точного результату операції.
  • underflow, встановлюється, якщо округлене значення крихітне (як визначено в IEEE 754) і неточне (або, можливо, обмежене, якщо воно має втрати денормалізації, згідно з версією IEEE 754 1985 року), повертаючи субнормальне значення, включаючи нулі.
  • overflow, встановлюється, якщо абсолютне значення округленого значення занадто велике для представлення. Повертається нескінченне або максимальне кінцеве значення, залежно від того, яке округлення використовується.
  • divide-by-zero, встановлюється, якщо результат нескінченний із заданими кінцевими операндами, повертаючи нескінченність, або +∞, або −∞.
  • invalid, встановлюється, якщо дійсний результат не може бути повернутий, наприклад sqrt(-1) або 0/0, повертаючи тихий NaN.

Значення, що повертається за замовчуванням для кожного з винятків, призначене для надання правильного результату в більшості випадків, так що винятки можна ігнорувати в більшості кодів. inexact повертає правильно округлений результат, а underflow повертає значення, яке менше або дорівнює найменшому позитивному нормальному числу за величиною, і його майже завжди можна ігнорувати. divide-by-zero точно повертає нескінченність, яка, як правило, потім ділить скінченне число та дає нуль, або згодом видає недійсний виняток, якщо ні, і тому його також зазвичай можна ігнорувати. Наприклад, ефективний опір n резисторів, з’єднаних паралельно (див. рис. 1), визначається як. Якщо виникає коротке замикання з встановити 0, поверне +нескінченність, що дасть фінал 0, як і очікувалося (див. приклад обґрунтування дизайну IEEE 754 для іншого прикладу).

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

Проблеми з точністю

[ред. | ред. код]

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

Наприклад, десяткові числа 0,1 і 0,01 не можуть бути представлені точно як двійкові числа з рухомою комою. У двійковому32 форматі IEEE 754 з його 24-бітною мантисою спроби звести наближення до 0,1 не є ані 0,01, ані найближче до нього число, яке можна представити. Десяткове число 0,1 представлено у двійковій системі як e  = −4 ; s  = 110011001100110011001101, тобто

0,100000001490116119384765625 точно.

Зведення цього числа в квадрат дає

0,010000000298023226097399174250313080847263336181640625 точно.

Зведення його в квадрат із округленням до 24-бітної точності дає

0,010000000707805156707763671875 точно.

Але число, яке можна представити найближче до 0,01, є

0,009999999776482582092285156250 точно.

Крім того, нерепрезентативність π (та π/2) означає, що спроба обчислення tan(π/2) не дасть результату нескінченності, і навіть не буде переповнення у звичайних форматах з рухомою комою (за умови точного виконання тен). Стандартне апаратне забезпечення з рухомою комою просто не може спробувати обчислити tan(π/2), оскільки π/2 не може бути представлено точно. Це обчислення в C:

/* Достатньо цифр, щоб переконатися, що ми отримуємо правильне наближення. */ 
подвійне пі = 3,1415926535897932384626433832795 ; подвійний z = тан (пі / 2,0);   
   

дасть результат 16331239353195370,0. З одиничною точністю (з використанням tanfфункції) результат буде −22877332,0.

Таким же чином, спроба обчислення sin(π) не дасть нуля. Результат буде (приблизно) 0,1225 × 10 −15 з подвійною точністю або −0,8742 × 10 −7 з одинарною точністю.

Хоча додавання та множення з рухомою комою комутативні (a + b = b + a та a × b = b × a), вони не обов’язково асоціативні. Тобто (a + b) + c не обов’язково дорівнює a + (b + c). Використовуючи 7-значну та десяткову арифметику:

a = 1234,567, b = 45,67834, c = 0,0004
(a + b) + c:
     1234.567 (a)
   + 45,67834 (б)
   ____________
     1280,24534 округляється до 1280,245
    1280,245 (а + б)
   + 0,0004 (c)
   ____________
    1280,2454 округляється до    1280,245   ← (a + b) + c
a + (b + c):
   45,67834 (б)
 + 0,0004 (c)
 ____________
   45,67874
   1234.567 (a)
 + 45,67874 (б + в)
 ____________
   1280,24574 округлює до    1280,246 ← a + (b + c)

Вони також не обов'язково є розподільними. Тобто (a + b) × c може не збігатися з a × c + b × c :

1234,567 × 3,333333 = 4115,223
 1,234567 × 3,333333 = 4,115223
                       4115,223 + 4,115223 = 4119,338
 але
 1234,567 + 1,234567 = 1235,802
                       1235,802 × 3,333333 = 4119,340

Окрім втрати значущості, неможливості точного представлення таких чисел, як π і 0,1, та інших незначних неточностей, можуть виникнути такі явища:

  • Скасування : віднімання майже рівних операндів може призвести до надзвичайної втрати точності. Коли ми віднімаємо два майже рівні числа, ми встановлюємо старші цифри рівними нулю, залишаючи собі лише незначущі та найбільш помилкові цифри. Наприклад, при визначенні похідної функції використовується наступна формула: Інтуїтивно зрозуміло, що h буде дуже близьким до нуля; однак, коли використовуються операції з рухомою комою, найменше число не дасть найкращого наближення похідної. Коли h стає меншим, різниця між f (a + h) і f (a) зменшується, скасовуючи найбільш значущі та найменш помилкові цифри, а найбільш хибні цифри стають більш важливими. У результаті найменше можливе число h дасть більш хибне наближення похідної, ніж дещо більше число. Це, мабуть, найпоширеніша і серйозна проблема точності.
  • Перетворення в ціле число не є інтуїтивно зрозумілим: перетворення (63,0/9,0) у ціле число дає 7, але перетворення (0,63/0,09) може дати 6. Це тому, що перетворення зазвичай скорочуються, а не округлюються. Функції підлоги та стелі можуть давати відповіді, які на одиницю відрізняються від інтуїтивно очікуваного значення.
  • Обмежений діапазон експонент: результати можуть бути переповненими, що дасть нескінченність, або заниженим, що дасть субнормальне число або нуль. У цих випадках точність буде втрачена.
  • Перевірка безпечного ділення проблематична: перевірка того, що дільник не дорівнює нулю, не гарантує, що ділення не переповниться.
  • Перевірка на рівність є проблематичною. Дві математично рівні обчислювальні послідовності цілком можуть давати різні значення з рухомою комою.

Інциденти

[ред. | ред. код]
  • 25 лютого 1991 року ракетна батарея MIM -104 Patriot втратила значення і не змогла перехопити ракету «Скад», що наближалася в Дахрані, Саудівська Аравія, що призвело до загибелі 28 солдатів 14-го інтендантського загону армії США.

Точність машини та аналіз зворотних помилок

[ред. | ред. код]

Машинна точність — це величина, яка характеризує точність системи з рухомою комою та використовується в зворотному аналізі помилок алгоритмів з рухомою комою. Він також відомий як одиниця округлення або машинний епсилон. Зазвичай позначається Ε mach, його значення залежить від конкретного округлення, яке використовується.

З округленням до нуля, тоді як округлення до найближчого, де B — основа системи, а P — точність мантиси (в основі B).

Це важливо, оскільки воно обмежує відносну похибку в представленні будь-якого ненульового дійсного числа x у межах нормалізованого діапазону системи з рухомою комою: Зворотний аналіз помилок, теорія якого була розроблена та популяризована Джеймсом Х. Вілкінсоном, може бути використана для встановлення того, що алгоритм, який реалізує числову функцію, чисельно стабільний. Основний підхід полягає в тому, щоб показати, що хоча обчислений результат через помилки округлення не буде точно правильним, він є точним рішенням сусідньої проблеми з дещо збуреними вхідними даними. Якщо необхідне збурення невелике, на рівні невизначеності у вхідних даних, то результати в певному сенсі настільки точні, наскільки дані «заслуговують». Тоді алгоритм визначається як зворотно стабільний. Стабільність - це міра чутливості до помилок округлення даної чисельної процедури; навпаки, номер умови функції для даної проблеми вказує на притаманну чутливість функції до невеликих збурень на її вході та не залежить від реалізації, яка використовується для вирішення проблеми.

Мінімізація впливу проблем із точністю

[ред. | ред. код]

Хоча окремі арифметичні операції IEEE 754 гарантовано точні з точністю до половини ULP, складніші формули можуть мати більші помилки з різних причин. Втрата точності може бути суттєвою, якщо проблема або її дані погано обумовлені, тобто правильний результат надчутливий до дрібних збурень у своїх даних. Однак навіть добре обумовлені функції можуть постраждати від значної втрати точності, якщо для цих даних використовується чисельно нестабільний алгоритм: очевидно еквівалентні формулювання виразів на мові програмування можуть помітно відрізнятися своєю чисельною стабільністю. Одним із підходів до усунення ризику такої втрати точності є розробка та аналіз чисельно стабільних алгоритмів, що є метою розділу математики, відомого як чисельний аналіз. Іншим підходом, який може захистити від ризику чисельної нестабільності, є обчислення проміжних (скретч-значень) в алгоритмі з вищою точністю, ніж вимагає кінцевий результат, що може видалити або зменшити на порядки такий ризик: IEEE 754 чотирикратна точність і розширена точність розроблені для цієї мети при обчисленні з подвійною точністю.

Наприклад, наступний алгоритм є прямою реалізацією для обчислення функції A (x) = (x −1) / (exp( x −1) − 1), яка добре обумовлена на 1,0, однак вона може виявляється чисельно нестабільним і втрачає до половини значущих цифр, що містяться в арифметиці, коли обчислюється близько 1,0.

double A(double X)
{
        double Y, Z;  // [1]
        Y = X - 1.0;
        Z = exp(Y);
        if (Z != 1.0)
                Z = Y / (Z - 1.0); // [2]
        return Z;
}

Проте, якщо всі проміжні обчислення виконуються з підвищеною точністю (наприклад, встановлюючи рядок [1] на C99 long double), тоді можна підтримувати повну точність кінцевого подвійного результату. Альтернативно, чисельний аналіз алгоритму показує, що якщо внести наступну неочевидну зміну до рядка [2]:

Z = log(Z) / (Z - 1.0);

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

Для підтримки властивостей таких ретельно побудованих чисельно стабільних програм потрібне обережне поводження з компілятором. Певні «оптимізації», які можуть зробити компілятори (наприклад, операції зміни порядку), можуть працювати проти цілей правильного програмного забезпечення. Існують деякі суперечки щодо недоліків компіляторів і дизайну мови в цій області: C99 є прикладом мови, де такі оптимізації ретельно визначені для підтримки чисельної точності. Перегляньте зовнішні посилання внизу цієї статті.

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

Оскільки десяткові дроби часто не можуть бути точно представлені у двійковій формі з рухомою комою, така арифметика є найкращою, коли її просто використовують для вимірювання реальних величин у широкому діапазоні масштабів (таких як орбітальний період місяця навколо Сатурна). або маса протона), і в гіршому випадку, коли очікується моделювання взаємодії величин, виражених у вигляді десяткових рядків, які, як очікується, будуть точними. Прикладом останнього випадку є фінансові розрахунки. З цієї причини фінансове програмне забезпечення, як правило, не використовує двійкове представлення чисел з рухомою комою. «Десятковий» тип даних мов програмування C# і Python, а також десяткові формати стандарту IEEE 754-2008 розроблені для уникнення проблем двійкових представлень із рухомою комою при застосуванні до введених людиною точних десяткових значень., і зробити так, щоб арифметика завжди поводилася належним чином, коли числа друкуються в десятковому вигляді.

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

Використання перевірки рівності (if (x==y) ...) вимагає обережності при роботі з числами з рухомою комою. Навіть такі прості вирази, як 0.6/0.2-3==0, на більшості комп’ютерів не відповідають дійсності (у IEEE 754 подвійна точність, наприклад, 0.6/0.2 - 3приблизно дорівнює -4,44089209850063e-16). Отже, такі тести іноді замінюють «нечіткими» порівняннями (if (abs(x-y) < epsilon) ..., де епсилон достатньо малий і адаптований до програми, наприклад 1.0E−13). Доцільність робити це дуже різна, і може знадобитися числовий аналіз для обмеження епсилона. Значення, отримані з представлення первинних даних, і їх порівняння повинні виконуватися з ширшою, розширеною точністю, щоб мінімізувати ризик таких невідповідностей через помилки округлення. Часто краще організувати код таким чином, щоб такі тести були непотрібними. Наприклад, в обчислювальній геометрії точні перевірки того, чи лежить кома на прямій або площині, визначеній іншими комами, можна виконати за допомогою методів адаптивної точності або точної арифметики.

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

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

3253,671
+ 3,141276
-----------
3256,812

Молодші 3 цифри доданків фактично втрачаються. Припустимо, наприклад, що потрібно додати багато чисел, усі приблизно дорівнюють 3. Після додавання 1000 з них поточна сума становить близько 3000; втрачені цифри не відновлюються. Алгоритм підсумовування Кахана може бути використаний для зменшення помилок. Помилка округлення може вплинути на збіжність і точність ітераційних чисельних процедур. Наприклад, Архімед апроксимував π шляхом обчислення периметрів багатокутників, що вписують і описують коло, починаючи з шестикутників і послідовно подвоюючи кількість сторін. Як зазначалося вище, обчислення можуть бути переорганізовані таким чином, щоб бути математично еквівалентним, але менш схильним до помилок (числовий аналіз).

Дві форми рекурентної формули для описаного многокутника: [ потрібна цитата ]

  • перша форма:
  • друга форма:
  • , що сходяться як

Ось обчислення з використанням арифметики IEEE "double" (мантиса з точністю 53 біти):

i 6 × 2 i × t i, перша форма 6 × 2 i × t i, друга форма
-------------------------------------------------- -------
 0    3 .4641016151377543863       3 .4641016151377543863
 1    3 .2153903091734710173       3 .2153903091734723496
 2    3,1 596599420974940120       3,1 596599420975006733
 3    3,14 60862151314012979       3,14 60862151314352708
 4    3,14 27145996453136334       3,14 27145996453689225
 5    3,141 8730499801259536       3,141 8730499798241950
 6    3,141 6627470548084133       3,141 6627470568494473
 7    3,141 6101765997805905       3,141 6101766046906629
 8    3,14159 70343230776862       3,14159 70343215275928
 9    3,14159 37488171150615       3,14159 37487713536668
10    3,141592 9278733740748       3,141592 9273850979885
11    3,141592 7256228504127       3,141592 7220386148377
12    3,1415926 717412858693       3,1415926 707019992125
13    3,1415926 189011456060       3,14159265 78678454728
14    3,1415926 717412858693       3,14159265 46593073709
15    3,14159 19358822321783       3,141592653 8571730119
16    3,1415926 717412858693       3,141592653 6566394222
17    3,1415 810075796233302       3,141592653 6065061913
18    3,1415926 717412858693       3,1415926535 939728836
19    3,141 4061547378810956       3,1415926535 908393901
20    3,14 05434924008406305       3,1415926535 900560168
21    3,14 00068646912273617       3,141592653589 8608396
22    3,1 349453756585929919       3,141592653589 8122118
23    3,14 00068646912273617       3,14159265358979 95552
24    3 .2245152435345525443       3.14159265358979 68907
25                               3,14159265358979 62246
26                               3,14159265358979 62246
27                               3,14159265358979 62246
28                               3,14159265358979 62246
              Справжнє значення 3,14159265358979323846264338327...

Хоча дві форми рекурентної формули явно математично еквівалентні, перша віднімає 1 від числа, дуже близького до 1, що призводить до все більш проблематичної втрати значущих цифр. Коли рецидив застосовується багаторазово, точність спочатку покращується, але потім погіршується. Він ніколи не стає кращим, ніж приблизно 8 цифр, навіть якщо 53-бітна арифметика повинна мати точність приблизно 16 цифр. Коли використовується друга форма повторення, значення збігається з точністю до 15 цифр.

Оптимізація "Швидка математика".

[ред. | ред. код]

Вищезазначена відсутність асоціативності операцій з рухомою комою загалом означає, що компілятори не можуть так само ефективно перевпорядковувати арифметичні вирази, як вони могли б з цілочисельною арифметикою та арифметикою з фіксованою комою, створюючи перешкоду для оптимізації, такої як усунення загальних підвиразів і автовекторизація. Опція «швидкої математики» в багатьох компіляторах (ICC, GCC, Clang, MSVC...) вмикає реасоціацію разом із небезпечними припущеннями, такими як відсутність NaN і нескінченні числа в IEEE 754. Деякі компілятори також пропонують більш деталізацію параметри, щоб увімкнути лише реасоціацію. У будь-якому випадку програміст наражається на багато пасток точності, згаданих вище для частини програми, яка використовує «швидку» математику.

У деяких компіляторах (GCC і Clang) увімкнення «швидкої» математики може призвести до того, що програма вимкне субнормальні числа з рухомою комою під час запуску, впливаючи на поведінку з рухомою комою не лише згенерованого коду, але й будь-якої програми, яка використовує такий код як бібліотеку.

У більшості компіляторів Fortran, як це дозволено стандартом ISO/IEC 1539-1:2004 Fortran, повторна асоціація є типовою, а пошкодження значною мірою запобігає налаштування «захистити дужки» (також увімкнено за замовчуванням). Цей параметр запобігає повторному асоціюванню компілятора за межами дужок. Компілятор Intel Fortran є помітним викидом.

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

«Рухома кома» та «рухома крапка»

[ред. | ред. код]

В англомовних країнах (див. докладний список десятковий розділювач) при запису чисел ціла частина відділяється від дробової крапкою, то в термінології цих країн фігурує назва «рухома крапка» (англ. floating point). Оскільки в Україні ціла частина числа від дробової традиційно відділяється комою, то для позначення того ж поняття історично використовується термін «рухома кома», проте в літературі та технічній документації можна зустріти обидва варіанти.

Походження назви

[ред. | ред. код]

Назва «рухома кома» походить від того, що кома в позиційному поданні числа (десяткова кома, або, для комп'ютерів, двійкова кома — далі по тексту просто кома) може бути поміщена де завгодно відносно цифр у рядку. Це положення коми вказується окремо у внутрішньому поданні. Таким чином, подання числа у формі з рухомою комою може розглядатися як комп'ютерна реалізація експоненційного запису чисел.

Перевага використання подання чисел у форматі з рухомою комою порівняно з використанням у форматі з фіксованою комоюцілими числами) полягає в тому, що можна використовувати істотно ширший діапазон значень за незмінної відносної точності. Наприклад, у формі з фіксованою комою число, що має 8 розрядів у цілій частині і 2 розряди після коми, можна подати у вигляді 123456,78; 8765,43; 123,00 і так далі. У свою чергу, у форматі з рухомою комою (в тих же 8 розрядах) можна записати числа 1,2345678; 1234567,8; 0,000012345678; 12345678000000000 і так далі, але для цього потрібне дворозрядне[прояснити] додаткове поле для запису показника степеня 10 від 0 до 1610, при цьому загальне число розрядів складе 8+2=10.

Швидкість виконання комп'ютером операцій з числами, поданими у формі з рухомою комою, вимірюється в мегафлопсах (від англ. FLOPS — число операцій з рухомою комою за секунду), гігафлопсах і так далі, і є однією з основних одиниць вимірювання швидкодії обчислювальних систем.

Нормальна форма та нормалізована форма

[ред. | ред. код]

Нормальною формою числа з рухомою комою називається така форма, в якій мантиса (без урахування знаку) міститься на напівінтервалі [0; 1) (). Така форма запису має недолік: деякі числа записуються неоднозначно (наприклад, 0,0001 можна записати в 4 формах — 0,0001× 100, 0,001× 10-1, 0,01× 10-2, 0,1× 10-3), тому поширеною (особливо в інформатиці) є й інша форма запису — нормалізована, в якій мантиса десяткового числа набуває значень від 1 (включно) до 10 (НЕ включно), а мантиса двійкового числа набуває значень від 1 (включно) до 2 (НЕ включно) (). У такій формі будь-яке число (крім 0) записується єдиним чином. Недолік полягає в тому, що в такому вигляді неможливо отримати 0, тому представлення чисел в інформатиці передбачає спеціальну ознаку (біт) для числа 0.

Оскільки старший розряд (ціла частина числа) мантиси двійкового числа (крім 0) в нормалізованому вигляді дорівнює «1», то при записі мантиси числа в ЕОМ старший розряд можна не записувати, що й використовується в стандарті IEEE 754. В позиційних системах числення з основою, більшою, ніж 2 (у трійковій, четвірковій та інших), цієї властивості немає.

Використання в обчислювальних машинах

[ред. | ред. код]

В обчислювальних машинах показник степеня прийнято відокремлювати від мантиси літерою «E» (англ. exponent). Наприклад, число 1,528535047× 10-25 у більшості мов програмування високого рівня записується як 1.528535047E-25.

Див. також

[ред. | ред. код]

Примітки

[ред. | ред. код]
  1. number // Англійсько-український словник з математики та інформатики 2010 р. (Є. Мейнарович, М. Кратко).
  2. number // Англійсько-українсько-англійський словник наукової мови (фізика та споріднені науки). Частина І англійсько-українська 2010 р. (О. Кочерга, Є. Мейнарович).
  3. число // Українсько-англійський словник з радіоелектроніки 2015 (Богдан Рицар, Леонід Сніцарук, Роман Мисак).

Посилання

[ред. | ред. код]

Література

[ред. | ред. код]
  • Криницкий Н. А., Миронов Г. А., Фролов Г. Д. Программирование. — М. : Государственное издательство физико-математической литературы, 1963. — 384 с.
  • Генри С. Уоррен, мл. Глава 15. Числа с плавающей точкой // Алгоритмические трюки для программистов = Hacker's Delight. — М. : Вильямс, 2007. — С. 288. — ISBN 0-201-91465-4.