Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Тема 10. Алгоритми роботи з дійсними числами.






 

Дійсні числа представляються в комп'ютері в так названої експонентної, або плаваючої, форми. Дійсне число r має вигляд

r = ±2e* m

Подання числа складається з трьох елементів:

1. знак числа - плюс або мінус. Під знак числа приділяється один біт у двійковому поданні, він розташовується в старшому, тобто знаковому розряді. Одиниця відповідає знаку мінус, тобто від’ємному числу, нуль - знаку плюс. У нуля знаковий розряд також нульовий;

2. показник ступеня e, його називають порядком або експонентою. Експонента вказує ступінь двійки, на яку множиться число. Експонента може бути як додатною, так і від’ємною (для чисел, менших одиниці). Під експоненту приділяється фіксоване число двійкових розрядів, звичайно вісім або одинадцять, розташованих у старшій частині двійкового подання числа, відразу слідом за знаковим розрядом;

3. мантиса m являє собою фіксовану кількість розрядів двійкового запису дійсного числа в діапазоні від 1 до 2:

4. 1 < = m< 2

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

У мові С# дійсним числам відповідають типи float й double. Елемент типу float займає 4 байти, у яких один біт приділяється під знак, вісім - під порядок, інші 23 - під мантису (насправді, у мантисі 24 розряду, але старший розряд завжди дорівнює одиниці, тому зберігати його не потрібно). Тип double займає 8 байтів, у них один розряд приділяється під знак, 11 - під порядок, інші 52 - під мантису. Насправді в мантисі 53 розряду, але старший завжди дорівнює одиниці й тому не зберігається. Оскільки порядок може бути додатнім і від’ємним, у двійковому коді він зберігається в зміщеному виді: до нього додається константа, рівна абсолютній величині максимального по модулю від’ємного порядку. У випадку типу float вона дорівнює 127, у випадку double - 1023. Таким чином, максимальний по модулю від’ємний порядок представляється нульовим кодом.

Арифметичний тип із плаваючою крапкою
Ім'я типу Системний тип Діапазон Точність
Float System.Single - 3. 402823e38 … + 3...402823e38 7 цифр
Double System.Double - 1. 79769313486232e308... 1.79769313486232e308 15-16 цифр

 

Основним типом є тип double, саме він найбільш природний для комп'ютера. У програмуванні треба по можливості уникати типу float, тому що його точність недостатня, а процесор однаково при виконанні операцій перетворить його в тип double. (Один з деяких випадків, де застосування типу float виправдано, - тривимірна комп'ютерна графіка.)

Кілька прикладів подання дійсних чисел у плаваючій формі:

1. 1.0 = +20*1.0

Тут порядок дорівнює 0, мантиса - 1. У двійковому коді мантиса складається з одних нулів, тому що старший розряд мантиси (завжди одиничний) у коді відсутній. Порядок зберігається у двійковому коді в зміщеному виді, він дорівнює 127 у випадку float й 1023 у випадку double;

2. 3.5 = +21*1.75

Порядок дорівнює одиниці, мантиса складається із трьох одиниць, з яких у двійковому коді зберігаються дві: 1100...0; зміщений порядок дорівнює 128 для float й 1024 для double;

3. 0. 625 = +2-1*1.25

Порядок від’ємний і дорівнює -1, дробова частина мантиси дорівнює 0100...0; зміщений порядок дорівнює 126 для float й 1022 для double;

4. 100.0 = +26*1.5625

Порядок дорівнює шести, дробова частина мантиси дорівнює 100100...0; зміщений порядок дорівнює 133 для float й 1029 для double.

При виконанні додавання двох додатніх плаваючих чисел відбуваються наступні дії:

1. вирівнювання порядків. Визначається число з меншим порядком. Потім послідовно його порядок збільшується на одиницю, а мантиса ділиться на 2, поки порядки двох чисел не зрівнюються. Апаратно розподіл на 2 відповідає зрушенню двійкового коду мантиси вправо, так що ця операція виконується швидко. При зрушеннях праві розряди губляться, через це може відбутися втрата точності (у випадку, коли праві розряди ненульові);

2. додавання мантис;

3. нормалізація: якщо мантиса результату стала дорівнює або перевищила двійку, то порядок збільшується на одиницю, а мантиса ділиться на 2. У результаті цього мантиса попадає в інтервал 1 < =m< 2. При цьому можлива втрата точності, а також переповнення, коли порядок перевищує максимально можливу величину.

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

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

a+b = a при b 0

Більше того, для додавання не виконується закон асоціативності:

a+(b+c) (a+b)+c

Дійсно, нехай ε - максимальне плаваюче число серед чисел, що задовольняють умові

1.0+? = 1.0

(наведені вище міркування показують, що такі числа існують). Тоді

(1.0+ε)+ε 1.0+(? +?)

оскільки ліва частина нерівності дорівнює одиниці, а права строго більше одиниці (це слідує з максимальності числа ε).

Число ε часто називають машинним эпсилоном або, менш коректно, машинним нулем, оскільки при додатку до одиниці воно поводиться як нуль. Величина машинного эпсилона характеризує точність операцій комп'ютера. Вона приблизно однакова для всіх сучасних комп'ютерів: більшість процесорів працюють із восьмибайтовими плаваючими числами (тип double у С#), а арифметика плаваючих чисел підкоряється строгим міжнародним стандартам.

Визначимо величину машинного епсилону для типу double. Число 1.0 записується в плаваючій формі як 1.0 = +20*1.0.

Порядок плаваючого числа 1.0 дорівнює нулю. При додаванні 1.0 із числом ε виконується вирівнювання порядку шляхом багаторазового зрушення мантиси числа ε вправо й збільшення його порядку на 1. Оскільки всі розряди числа ε повинні в результаті вийти за межі розрядної сітки, повинно бути виконане 53 зрушення. Порядок числа ε після цього повине стати рівним порядку числа 1.0, тобто нулю. Отже, споконвічно порядок числа ε повине бути рівним -53:

ε = 2-53*m

де m - число в діапазоні від одиниці до двох. Таким чином, величина машинного эпсилона становить приблизно

2-53 10-16

Приблизно точність обчислень становить 16 десяткових цифр. (Це також можна оцінити в такий спосіб: 53 двійкових розрядів становлять приблизно 15.95 десяткових, оскільки 53/log210 53/3.321928 15.95.)

У випадку чотирьохбайтових плаваючих чисел (тип float мови С#) точність обчислень становить приблизно 7 десяткових цифр. Це дуже мало, тому тип float надзвичайно рідко застосовується на практиці. До того ж процесор сконструйований для роботи з восьмибайтовими дійсними числами, а при роботі із чотирьохбайтовими він однаково спочатку приводить їх до восьмибайтового типу. У програмуванні варто уникати типу float і завжди користуватися типом double.

Крім втрати точності, при операціях з дійсними числами можуть відбуватися й інші неприємності:

1. переповнення - коли порядок результату більше максимально можливого значення. Ця помилка часто виникає при множенні великих чисел;

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

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

1. нескінченно велике число - це плаваюче число з дуже великим додатнім порядком й, таким чином, дуже велике по абсолютній величині. Воно може мати знак плюс або мінус;

2. нескінченно мале, або денормалізоване, число - це ненульове плаваюче число, тобто дуже маленьке по абсолютній величині;

3. Not a Number, або Na - двійковий код, що не є коректним поданням якого-небудь дійсного числа.

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

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

1.2, 0.725, 1.,.35, 0.

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

Експонентна форма запису дійсної константи містить знак, мантису й десятковий порядок (експоненту). Мантиса - це будь-яка позитивна речовинна константа у формі з фіксованою крапкою або цілою константою. Порядок указує степінь числа 10, на яку домножується мантиса. Порядок відокремлюється від мантиси буквою " e" (від слова exponent), вона може бути прописною або рядковою. Порядок може мати знак плюс або мінус, у випадку позитивного порядку знак плюс можна опускати. Приклади:

1.5e+6 константа еквівалентна 1500000.01e-4 константа еквівалентна 0.0001-.75E3 константа еквівалентна -750.0

 


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.007 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал