2215

Программирование с использованием математического сопроцессора

Лабораторная работа

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

Необходимо разработать и отладить программу на языке Си, реализующую алгоритм вычисления функции (1+x)α, eps=10-17 путем разложения в ряд.

Русский

2013-01-06

70.91 KB

6 чел.

Федеральное агентство по образованию

Государственное образовательное учреждение

высшего профессионального образования

«Ижевский государственный технический университет»

Кафедра «Программное обеспечение»

Отчет

по лабораторной работе №1 на тему:

«Программирование с использованием

математического сопроцессора»

по дисциплине «Системное программное обеспечение»


Вариант 20

1. ПОСТАНОВКА ЗАДАЧИ

Необходимо разработать и отладить программу на языке Си, реализующую алгоритм вычисления функции (1+x)α, eps=10-17 путем разложения в ряд.

Функция реализуется 2 способами: первый – на «чистом» Си, второй с использованием ассемблерных вставок.

В качестве параметров в функцию передаются: аргумент функции, требуемая  точность вычислений. Для входных и выходных данных используются числа с плавающей точкой (long double).

Все вещественные переменные должны быть загружены в стек сопроцессора до выполнения основного цикла (внутри цикла обращение только к стеку). Целочисленные переменные могут находиться в памяти.

Возвращаемое значение можно оставить в st(0) и опустить соответствующий оператор return. Все остальные ячейки стека должны быть освобождены (для исключения ошибок выполнения).

Максимальное количество используемых в программе слагаемых не должно превышать 200, причем, чтобы не допустить переполнения, не вычислять факториалы и возведение в степень. Вычисление прекращать, когда достигнута заданная точность.

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

Для контрольного примера использовать соответствующую библиотечную функцию. Проверить исходные значения, расположенные вблизи нуля (как "слева", так и "справа") и числа левого и правого края допустимого диапазона значений аргумента.

На основании анализа полученных результатов, определить допустимый диапазон входных значений, рассчитать погрешности и оценить скорость вычисления обеих функций. Все результаты свести в таблицу.


2. МАТЕМАТИЧЕСКОЕ ОПИСАНИЕ

Разложим функцию (1+x)α в ряд:

Представим этот ряд в виде рекурсивных формул:

,

,

где ui+1, ui  - это (i+1)-й и i-й члены ряда,

k(i) - коэффициент связи (i+1)-го и i-го членов ряда,

qi+1, qi - суммы (i+1)-го и i-го членов ряда.

Определим значение k(i):

,

,

.

Таким образом, каждое новое слагаемое ряда может быть получено из предыдущего путем умножения его на k(i).


3. ОПИСАНИЕ ФУНКЦИЙ

3.1. Процедура main

Используемые модули:

#include <iostream> //для вывода и считывания с экрана

#include <windows.h> //для работы с таймером

#include <math.h> //для вычисления степеней  

Используемые константы:

#define eps powl(10,-17)

const int N=199;

Синтаксис:

void main ()

Входные данные:

Принимаемых значений нет.

Выходные данные:

Возвращаемых значений нет.

Описание:

Процедура выводит на экран информацию о программе и вводит x и a. После ввода, процедура производит вычисление функции (1+x)α тремя способами: с помощью библиотечной функции, разложением в ряд на «чистом» Си и разложением в ряд с использованием ассемблерных вставок, вызывая соответствующие функции (CFunc и AsmFunc). Для двух последних способов процедура рассчитывает погрешность результата (отличие от библиотечной функции) и затраченное время. Все полученные результаты выводятся на экран в виде таблицы.


3.2. Функция CFunc

Синтаксис:

long double CFunc(long double x,long double a,long double e)

Входные данные:

Аргумент функции x, степень , требуемая точность e.

Выходные данные:

Полученное значение функции (1+x)α.

Описание:

Функция реализована на «чистом» языке Си. Начиная с i=0 и q=u=1 функция высчитывает каждое новое слагаемое ряда u для каждого i и прибавляет его к q по формулам u=u∙x∙(a-i)/(i+1) и q=q+u. Вычисления прекращаются в случае |u|<e или i≥199, после чего функция возвращает q качестве полученного значения.

3.3. Функция AsmFunc

Синтаксис:

long double AsmFunc(long double x,long double a,long double e)

Входные данные:

Аргумент функции x, степень , требуемая точность e.

Выходные данные:

Полученное значение функции (1+x)α.

Описание:

Функция реализована с использованием ассемблерных вставок и команд математического сопроцессора. Функция загружает в стек сопроцессора e, x, a, 1(в качестве q), 1(в качестве u) и 0(в качестве i), после чего циклически, используя команды работы со стеком, вычисляет q для каждого i по уже указанным в описании функции CFunc формулам. В конце каждого цикла функция сравнивает текущее u с e, заносит в стек N=199 и сравнивает с текущим i. В случае |u|<e или i≥199 функция выходит из цикла, освобождает все ячейки стека, кроме st(0), и возвращает через него текущее значение q.


4. ОПИСАНИЕ КОНТРОЛЬНОГО ПРИМЕРА

4.1. Проверка исходных значений «слева» и «справа» от нуля

Программа вычисляет значение функции (1+x)^a c точностью eps=10e-17.

Введите аргумент функции х или 0 для выхода: 0,0000363

Введите a: 0,3

--------------------------------------------------------------------------------

Способ реализации       Полученный результат    Погрешность    Затраченное время

--------------------------------------------------------------------------------

Библиотечная функция    1,00001088986164530          -                  -

Разложение в ряд на

<чистом> Си             1,00001088986164530     0,000000e+000           0,000006

Разложение в ряд с

использованием ассем-

блерных вставок         1,00001088986164530     0,000000e+000           0,000002

--------------------------------------------------------------------------------

Нажмите Enter для выхода:

Программа вычисляет значение функции (1+x)^a c точностью eps=10e-17.

Введите аргумент функции х или 0 для выхода: 0,537338

Введите a: 2

--------------------------------------------------------------------------------

Способ реализации       Полученный результат    Погрешность    Затраченное время

--------------------------------------------------------------------------------

Библиотечная функция    2,36340812624400030          -                  -

Разложение в ряд на

<чистом> Си             2,36340812624400030     0,000000e+000           0,000006

Разложение в ряд с

использованием ассем-

блерных вставок         2,36340812624400030     0,000000e+000           0,000002

--------------------------------------------------------------------------------

Нажмите Enter для выхода:

Программа вычисляет значение функции (1+x)^a c точностью eps=10e-17.

Введите аргумент функции х или 0 для выхода: -0,000004563

Введите a: 2

--------------------------------------------------------------------------------

Способ реализации       Полученный результат    Погрешность    Затраченное время

--------------------------------------------------------------------------------

Библиотечная функция    0,99999087402082110          -                  -

Разложение в ряд на

<чистом> Си             0,99999087402082099     1,110223e-016           0,000006

Разложение в ряд с

использованием ассем-

блерных вставок         0,99999087402082099     1,110223e-016           0,000002

--------------------------------------------------------------------------------

Нажмите Enter для выхода:

Программа вычисляет значение функции (1+x)^a c точностью eps=10e-17.

Введите аргумент функции х или 0 для выхода: -0,4778383

Введите a: 0,4

--------------------------------------------------------------------------------

Способ реализации       Полученный результат    Погрешность    Затраченное время

--------------------------------------------------------------------------------

Библиотечная функция    0,77112006780077491          -                  -

Разложение в ряд на

<чистом> Си             0,77112006780077491     0,000000e+000           0,000014

Разложение в ряд с

использованием ассем-

блерных вставок         0,77112006780077491     0,000000e+000           0,000004

--------------------------------------------------------------------------------

Нажмите Enter для выхода:

4.2. Проверка левого и правого края области определения аргумента

Программа вычисляет значение функции (1+x)^a c точностью eps=10e-17.

Введите аргумент функции х или 0 для выхода: 0,9994435

Введите a: 3

--------------------------------------------------------------------------------

Способ реализации       Полученный результат    Погрешность    Затраченное время

--------------------------------------------------------------------------------

Библиотечная функция    7,99332385798115560          -                  -

Разложение в ряд на

<чистом> Си             7,99332385798115740     1,776357e-015           0,000006

Разложение в ряд с

использованием ассем-

блерных вставок         7,99332385798115740     1,776357e-015           0,000002

--------------------------------------------------------------------------------

Нажмите Enter для выхода:

Программа вычисляет значение функции (1+x)^a c точностью eps=10e-17.

Введите аргумент функции х или 0 для выхода: 0,754723

Введите a: 0,5

--------------------------------------------------------------------------------

Способ реализации       Полученный результат    Погрешность    Затраченное время

--------------------------------------------------------------------------------

Библиотечная функция    1,32465957891074800          -                  -

Разложение в ряд на

<чистом> Си             1,32465957891074780     2,220446e-016           0,000025

Разложение в ряд с

использованием ассем-

блерных вставок         1,32465957891074780     2,220446e-016           0,000004

--------------------------------------------------------------------------------

Нажмите Enter для выхода:

Программа вычисляет значение функции (1+x)^a c точностью eps=10e-17.

Введите аргумент функции х или 0 для выхода: -0,6899443

Введите a: 3

--------------------------------------------------------------------------------

Способ реализации       Полученный результат    Погрешность    Затраченное время

--------------------------------------------------------------------------------

Библиотечная функция    0,02980706119548852          -                  -

Разложение в ряд на

<чистом> Си             0,02980706119548854     1,734723e-017           0,000007

Разложение в ряд с

использованием ассем-

блерных вставок         0,02980706119548854     1,734723e-017           0,000002

--------------------------------------------------------------------------------

Нажмите Enter для выхода:

Программа вычисляет значение функции (1+x)^a c точностью eps=10e-17.

Введите аргумент функции х или 0 для выхода: -0,9999994963

Введите a: 2

--------------------------------------------------------------------------------

Способ реализации       Полученный результат    Погрешность    Затраченное время

--------------------------------------------------------------------------------

Библиотечная функция    0,00000000000025371          -                  -

Разложение в ряд на

<чистом> Си             0,00000000000025369     2,772892e-017           0,000006

Разложение в ряд с

использованием ассем-

блерных вставок         0,00000000000025369     2,772892e-017           0,000002

--------------------------------------------------------------------------------

Нажмите Enter для выхода:


5. РЕЗУЛЬТАТЫ ТЕСТИРОВАНИЯ

Допустимый диапазон входных значений аргумента программы, при котором соблюдается заданная точность, зависит от значения . Примем за константу, равную 3,32, и рассмотрим результаты, полученные с помощью программы, при разных аргументах X():

X

Функция CFunc

Функция AsmFunc

Результат

Погрешность

Время, c.

Результат

Погрешность

Время, c.

0,9

7,95012818421462160

1,776357e-015

0,000026

7,95012818421462160

1,776357e-015

0,000004

0,8

7,03889872957289510

8,881784e-016

0,000013

7,03889872957289510

8,881784e-016

0,000003

0,7

5,55072889146631350

1,776357e-015

0,000009

5,55072889146631350

1,776357e-015

0,000002

0,6

4,56359971123205190

8,881784e-016

0,000008

4,56359971123205190

8,881784e-016

0,000002

0,5

3,70488529661068670

8,881784e-016

0,000006

3,70488529661068670

8,881784e-016

0,000002

0,4

3,05594179682829780

8,881784e-016

0,0000010

3,05594179682829780

8,881784e-016

0,000002

0,3

2,38941079003852770

4,440892e-016

0,000009

2,38941079003852770

4,440892e-016

0,000002

0,2

1,80200264760545070

2,220446e-016

0,000004

1,80200264760545070

2,220446e-016

0,000001

0,1

1,36049945787732660

4,440892e-016

0,000003

1,36049945787732660

4,440892e-016

0,000001

-0,1

0,71154653068824758

1,110223e-016

0,000004

0,71154653068824758

1,110223e-016

0,000002

-0,2

0,47671493353268540

1,665335e-016

0,000004

0,47671493353268540

1,665335e-016

0,000001

-0,29

0,31598514723457455

7,568652e-017

0,000004

0,31598514723457455

7,568652e-017

0,000001

-0,4

0,19205629155083065

3,551115e-018

0,000005

0,19205629155083065

3,551115e-018

0,000002

-0,5

0,10657936147099460

1,387779e-018

0,000006

0,10657936147099460

1,387779e-018

0,000002

-0,59

0,04773524668127166

6,938894e-018

0,0000013

0,04773524668127166

6,938894e-018

0,000002

-0,7

0,02046923691997474

3,122502e-017

0,000009

0,02046923691997474

3,122502e-017

0,000002

-0,8

0,00552493134907596

7,285839e-017

0,000013

0,00552493134907596

7,285839e-017

0,000002

-0,9

0,00058884365535573

1,432231e-016

0,000022

0,00058884365535573

1,432231e-016

0,000004

Исходя из данной таблицы, можно сделать вывод, что заданная точность достигается при X=(-0,3;-0,6). Также, были обнаружены некоторые точки, вблизи которых резко возрастала точность. Все это не позволяет получить окончательный вид зависимости без многократного увеличения числа измеренных точек X. Опытным путем было получено, что при увеличении диапазон допустимых значений сужается, а при уменьшении - увеличивается. За константу также можно было взять x и составить подобную таблицу для . В данном случае принятие одной из величин за константу является единственным способом определить интервал допустимых значений другой величины.

Таблица показывает, что функция, реализованная с помощью ассемблерных вставок, в любом случае выполняется быстрее, чем на «чистом» Си, при идентичных результатах и погрешностях. Ассемблер, как язык низкого уровня, работает непосредственно с процессором и меньше с памятью. При этом в ассемблерной функции были также использованы команды математического сопроцессора. Этим и обусловлено от двукратного до шестикратного преимущество в скорости функции AsmFunc над функцией CFunc.

Однако нельзя обойти и недостатки реализации на Ассемблере: более громоздкий и непонятный код, большее количество операций при вычислениях.


6. ТЕКСТ ПРОГРАММЫ

#include <iostream> //для вывода и считывания с экрана

#include <windows.h> //для работы с таймером

#include <math.h> //для вычисления степеней

#define eps powl(10,-17)

const int N=199;

long double CFunc(long double x,long double a,long double e){

   long double q=1,u=1;

   for(int i=0;(abs(u)>e)&&(i<N);i++) {

       u*=(x*(a-i))/(i+1);

       q+=u;

   }

   return (q);

}

long double AsmFunc(long double x,long double a,long double e){

__asm {

   fld e                //st(0)=e

   fld x                //st(0)=x; st(1)=e

   fld a                //st(0)=a; st(1)=x; st(2)=e

   fld1                 //st(0)=1; st(1)=a; st(2)=x; st(3)=e

   fld1                 //st(0)=1; st(1)=1; st(2)=a; st(3)=x; st(4)=e

   fldZ                 //st(0)=0; st(1)=1; st(2)=1; st(3)=a; st(4)=x; st(5)=e        

cycle:         //st(0)=i; st(1)=u; st(2)=q; st(3)=a; st(4)=x; st(5)=e        

   fldZ                 //st(0)=0; st(1)=i; st(2)=u; st(3)=q; st(4)=a; st(5)=x; st(6)=e        

   fadd st(0),st(1)     //st(0)=i; st(1)=i; st(2)=u; st(3)=q; st(4)=a; st(5)=x; st(6)=e        

   fsubr st(0),st(4)    //st(0)=a-i; st(1)=i; st(2)=u; st(3)=q; st(4)=a; st(5)=x; st(6)=e        

   fmul st(0),st(5)     //st(0)=x(a-i);st(1)=i;st(2)=u;st(3)=q;st(4)=a;st(5)=x;st(6)=e

   fld1             //st(0)=1;st(1)=x(a-i);st(2)=i;st(3)=u;st(4)=q;st(5)=a;st(6)=x;st(7)=e

   faddp st(2),st(0)    //st(0)=x(a-i);st(1)=i+1;st(2)=u;st(3)=q;st(4)=a;st(5)=x;st(6)=e

   fdiv st(0),st(1) //st(0)=x(a-i)/(i+1);st(1)=i+1;st(2)=u;st(3)=q;st(4)=a;st(5)=x;st(6)=e

   fmulp st(2),st(0)    //st(0)=i+1;st(1)=ux(a-i)/(i+1);st(2)=q;st(3)=a;st(4)=x;st(5)=e

   fldZ           //st(0)=0;st(1)=i+1;st(2)=ux(a-i)/(i+1);st(3)=q;st(4)=a;st(5)=x; st(6)=e

   fadd st(0),st(3)//st(0)=q;st(1)=i+1;st(2)=ux(a-i)/(i+1);st(3)=q;st(4)=a;st(5)=x;st(6)=e

   fadd st(0),st(2)    

   fldZ             

   fadd st(0),st(3)    

//st(0)=ux(a-i)/(i+1);st(1)=q+ux(a-i)/(i+1);st(2)=i+1;st(3)=ux(a-i)/(i+1);st(4)=q;st(5)=a;st(6)=x;st(7)=e

   fabs                //вычисление абсолютного значения st(0)

   fcomp st(7)            

   fstsw ax            // сравнение с eps -> st(7) и выталкивание st(0)

   sahf                

   jbe end  

   fst st(3)                    

   fild N                

//st(0)=N; st(1)=q+ux(a-i)/(i+1);st(2)=i+1;st(3)=ux(a-i)/(i+1);st(4)=q+ux(a-i)/(i+1);st(5)=a;st(6)=x;st(7)=e

   fcomp st(2)

   fstsw ax            // сравнение N с i и выталкивание st(0)

   sahf                

   jbe end                

   fcomp

   jmp cycle //st(0)=i+1;st(1)=ux(a-i)/(i+1);st(2)=q+ux(a-i)/(i+1);st(3)=a;st(4)=x;st(5)=e

end:  //st(0)=q+ux(a-i)/(i+1);st(1)=i+1;st(2)=ux(a-i)/(i+1);st(3)=q;st(4)=a;st(5)=x;st(6)=e                                

   ffree st(1)

   ffree st(2)

   ffree st(3)

   ffree st(4)

   ffree st(5)

   ffree st(6)

   }

}

void main () {    

   setlocale(LC_ALL,"Russian");

   system("cls");

   printf("Программа вычисляет значение функции (1+x)^a c точностью eps=10e-17.\nВведите аргумент функции х или 0 для выхода: ");

   long double x;

   scanf("%Lf",&x);

   if (x!=0) {

       printf("Введите a: ");

       long double a;

       scanf("%Lf",&a);

       printf("--------------------------------------------------------------------------------Способ реализации\tПолученный результат\tПогрешность    Затраченное время--------------------------------------------------------------------------------");

       LARGE_INTEGER freq,time1,time2;        

       long double brez,rez;

       QueryPerformanceFrequency(&freq);

       QueryPerformanceCounter(&time1);

       brez=powl(1+x,a);

       QueryPerformanceCounter(&time2);

       time2.QuadPart-=time1.QuadPart;

       printf("Библиотечная функция\t%.17lf\t     -\t\t\t-\n\n",brez);

       QueryPerformanceFrequency(&freq);

       QueryPerformanceCounter(&time1);

       rez=CFunc(x,a,eps);

       QueryPerformanceCounter(&time2);

       time2.QuadPart-=time1.QuadPart;

       printf("Разложение в ряд на\n«чистом» Си\t\t%.17lf\t%e\t\t%f\n\n",rez,abs(brez-rez),(double)time2.QuadPart/freq.QuadPart);

       QueryPerformanceFrequency(&freq);

       QueryPerformanceCounter(&time1);

       rez=AsmFunc(x,a,eps);

       QueryPerformanceCounter(&time2);

       time2.QuadPart-=time1.QuadPart;

       printf("Разложение в ряд с\nиспользованием ассем-\nблерных вставок \t%.17lf\t%e\t\t%f\n",rez,abs(brez-rez),(double)time2.QuadPart/freq.QuadPart);        

       printf("--------------------------------------------------------------------------------Нажмите Enter для выхода: ");    

       getchar();

       getchar();

   }

}


 

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

28963. СССР в 70-80-е годы XX в. Нарастание кризисных явлений в обществе 31.5 KB
  СССР в 7080е годы XX в. Советская экономика всё больше отставала от экономики развитых стран по техническому и технологическому уровню показателям эффективности и что более важно СССР утрачивал преимущества в темпах экономического роста. По этому показателю СССР отставал не только от ведущих западных стран но и от новых индустриальных стран Южной Кореи Тайваня на десятилетия. Чтобы покупать новейшие технологии и продовольствие СССР вынужден был всё больше сырья поставлять на экспорт.
28964. Политика перестройки, замыслы и результаты 40 KB
  Попрежнему формально высшим органом власти был двухпалатный Верховный Совет СССР регулярно собиравшийся на свои сессии на которых он утверждал решения партии и правительства. 12я внеочередная сессия Верховного Совета СССР приняла закон Об изменениях и дополнениях Конституции Основному Закону СССР содержанием которого было изменение избирательной системы в СССР принципов выборности народных депутатов СССР и принципов функционирования государственных органов. были проведены выборы народных депутатов СССР а весной 1990 г. Всего...
28965. События 1991, распад СССР, образование СНГ и выбор Россией нового исторического пути 37 KB
  Процесс затягивается4 8 декабря Беловежское соглашение Ельцын Кравчук Шушкевич : СССР прекращает существование Россия Украина и Белоруссия объединяются в СНГ. 5 21 декабря АлмаАтинская встреча лидерорв 9 республик Декларация о прекращении существования СССР и о принципах деятельности СНГ.До конца 1991 к СНГ присоединились Молдова и Азербайджан всего в СНГ 11 государств 15 минут 3 прибалтийские республики6 Горбачев сложил свои полномочия.
28966. Россия на пути социально-экономической модернизации. Октябрьские события 1993, завершающий этап ликвидации советской власти 30.5 KB
  явились следствием противостояния законодательной и исполнительной ветвей власти Российской Федерации. Ельцин издал указ О поэтапной конституционной реформе в Российской Федерации в соответствии с которым Верховный Совет и Съезд народных депутатов прекращали свою деятельность. Конституционный суд РФ пришел к заключению о несоответствии данного указа российской Конституции однако Ельцин его не отменил. В 1994 арестованные участники этих драматических событий были амнистированы Государственной думой Российской Федерации.
28967. Принятие конституции РФ 1993г. Качественные изменения социально политической жизни страны 36.5 KB
  Качественные изменения социально политической жизни страны Работа Конституционной комиссии Необходимость принятия новой Конституции была осознана всеми политическими силами еще в ходе принятия Декларации о государственном суверенитете от 12 июня 1990 г. Поначалу работа комиссии проходила довольно быстро и уже через четыре месяца проект новой Конституции был не только подготовлен но и опубликован для всеобщего обсуждения. Седьмой съезд постановил вынести основные положения проекта новой Конституции на всероссийский референдум но восьмой...
28968. Реформы 60-70-х гг. XIXв., их цели и содержание 36.5 KB
  их цели и содержание Реформа местного самоуправления земская и городская Отмена крепостного права привела к необходимости проведения буржуазных реформ и в других областях государственной жизни. по типу земской была проведена городская реформа. Военная реформа Поражение России в Крымской войне показало что необходимо реконструировать всю военную систему. Военная реформа проводилась до 1874 г.
28969. Революционное народничество, его идеология и политическая практика 37 KB
  Революционное народничество его идеология и политическая практика Возникновение народничества. Три течения в народничестве Идеи общинного социализма Герцена и Чернышевского стали основой политического течения радикальной интеллигенции народничества. Народники рассматривали народ крестьянство как реальную политическую силу хотели поднять его на революцию полагали что Россия может прийти к новому справедливому строю социализму минуя капитализм. Народничество стало ведущим направлением в освободительном движении оно имело свою...
28970. Реформы и контрреформы Александра III 26.5 KB
  Реформы и контрреформы Александра III 1. Александр III правил с 1881 по 1894 гг. После убийства отца Александр III выдвинул программу своего царствования: подавление оппозиции революционного движения; укрепление основ российской жизни самодержавия православия народности. Александру III было известно что перед смертью его отец одобрил проект либеральных реформ М.
28971. Характер и особенности социально-экономического развития России во второй половине XIX в. 55 KB
  Характер и особенности социальноэкономического развития России во второй половине XIX в. Промышленный переворот в России начался в конце 30х годов XIX века он имел 2 стороны: техническую переход от мануфактуры к фабрике замена ручного труда машинным; социальную формирование промышленного рабочего класса и класса буржуазии. К 80м годам сформировались основные промышленные районы России: Московский; Петербургский; Прибалтийский; Уральский; Южный Донбасс и Криворожье; Бакинский....