3573

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

Лекция

Информатика, кибернетика и программирование

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

Украинкский

2012-11-03

89.5 KB

4 чел.

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

Дійсні числа представляються в комп'ютері в так названої експонентної, або плаваючої, форми. Дійсне число 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;

  1.  3.5 = +21*1.75

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

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

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

  1.  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.0

1e-4 константа еквівалентна 0.0001

-.75E3 константа еквівалентна -750.0

Задача 10.1

Написати програму: Обчислити значення функції , коли х змінюється від А до В з кроком H. Результати вивести у вигляді таблиці " № розр.- Х- У". Врахувати не значимі значення аргументу. Використати відомі методи організації циклів.

Лістинг 10.1.. З використанням циклу for

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication3

{

class Program

{

static void Main(string[] args)

{

double a, b, h;

int i=0;

a = double.Parse(Console.ReadLine());

b = double.Parse(Console.ReadLine());

h = double.Parse(Console.ReadLine());

for (double x = a; x <= b; x = x + h)

{

i++;

if ((1 - x * x < 0) | (Math.Sin(1 - x) == 0))

{

Console.WriteLine(i + " " + x + " рішення немає ");

}

else

{

double y = Math.Sqrt(1 - x * x) / Math.Tan(1 - x);

Console.WriteLine(i + " " + x + " " + y);

} } } }}

Лістинг 10.2. З використанням циклу while

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication3

{

class Program

{

static void Main(string[] args)

{

double a, b, h;

int i=0;

a = double.Parse(Console.ReadLine());

b = double.Parse(Console.ReadLine());

h = double.Parse(Console.ReadLine());

double x = a;

while (x<=b)

{

i++;

if ((1 - x * x < 0) | (Math.Sin(1 - x) == 0))

{

Console.WriteLine(i + " " + x + " рішення немає ");

}

else

{

double y = Math.Sqrt(1 - x * x) / Math.Tan(1 - x);

Console.WriteLine(i + " " + x + " " + y);

}

x = x + h;

}

}

}

}

Лістинг 10.4.. З використанням циклу do while

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication3

{

class Program

{

static void Main(string[] args)

{

double a, b, h;

int i=0;

a = double.Parse(Console.ReadLine());

b = double.Parse(Console.ReadLine());

h = double.Parse(Console.ReadLine());

double x = a;

do

{

i++;

if ((1 - x * x < 0) | (Math.Sin(1 - x) == 0))

{

Console.WriteLine(i + " " + x + " рішення немає ");

}

else

{

double y = Math.Sqrt(1 - x * x) / Math.Tan(1 - x);

Console.WriteLine(i + " " + x + " " + y);

}

x = x + h;

}

while (x <= b);

}

}

}

Проаналізуйте наведені задачі, перевірте їх працездатність в середовищі програмування.


 

А также другие работы, которые могут Вас заинтересовать

7138. Понятие вины в уголовном праве 198.5 KB
  Понятие вины в уголовном праве Введение Состав преступления характеризуется совокупностью четырех элементов: объект, объективная сторона, субъект, субъективная сторона. Каждый из этих элементов является для любого состава обязательным. Отсутствие лю...
7139. Курортное оздоровление детей и подростков на российских и зарубежных курортах 218 KB
  Курортное оздоровление детей и подростков на российских и зарубежных курортах Введение Здоровье населения - один из важнейших элементов социального, культурного и экономического развития нашей страны. Именно поэтому Правительство Российской Федераци...
7141. Математическое описание двигателя постоянного тока независимого возбуждения 4.27 MB
  Содержание Математическое описание двигателя постоянного тока независимого возбуждения. Расчет параметров двигателя. Расчет контура тока. Расчет контура скорости...
7142. Экономическая эффективность использования основных производственных фондов 607.8 KB
  Экономическая эффективность использования основныхпроизводственных фондов Введение Животноводство является важной отраслью сельского хозяйства,дающей более половины его валовой продукции.Значение этой отрасли определяется не только...
7143. Электронная коммерция на примере интернет-магазина www.OZON.ru 307 KB
  Электронная коммерция на примере интернет-магазина www.OZON.ru Введение Начиная с середины 90-х годов, во всем мире наблюдается рост активности в области онлайновой торговли. Вслед за крупными компаниями, производящими компьютерное оборудование в Се...
7144. Финансирование строительства 183 KB
  ВВЕДЕНИЕ Кардинальная перестройка хозяйственного механизма основана на широком использовании товарно-денежных отношений, присущих рыночной экономике. Важнейшим экономическим инструментом товарно-денежных отношений служит кредит, который способствует...
7145. Исследование RC - автогенераторов для операционных усилителей с мостом Вина 1.76 MB
  Исследование RC - автогенераторов для операционных усилителей с мостом Вина Задание к курсовой работе: Задать номер варианта следующим образом: N=M M - две последние цифры номера зачетной книжки. Значение N определить по форму...
7146. Денежная масса и движение денег во внутреннем экономическом обороте страны 401.38 KB
  Введение Проблемами денег, организации денежного обращения человеческая мысль была занята больше, чем всеми остальными экономическими проблемами. С глубокой древности до наших дней вопросами теории денег занимались экономисты, философы, юристы. И се...