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();

   }

}


 

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

44643. Очистка нефтяных фракций селективными растворителями в экстракторе периодического действия 16.81 KB
  В результате селективной очистки существенно улучшаются два важнейших эксплуатационных свойства масел: стабильность против окисления и вязкостно-температурные свойства.
44644. Художественное моделирование из бумаги. Оригами по спирали 20.31 KB
  Цель: формирование практических навыков по выполнению оригами по спирали Задачи: 1.образовательные: Познакомить с технологией оригами по спирали развивающие: развивать логическое мышление развивать творческое воображение; воспитательные: воспитывать трудолюбие аккуратность дисциплинированность Оборудование: Для учителя: наглядный материалаппликация Для учащихся: нитки карандаш ножницы клей картон Оформление...
44645. Собственные и нарицательные имена существительные. Заглавная буква в именах существительных 19.77 KB
  Кто может еще что то добавить к этому правилу Потренируемся каждый из вас назовет свое собственное имя и так же нарицательное. пример: я учительница Бякова Наталья Сергеевна учительница – нарицательное Бякова Наталья Сергеевна – собственное я студентка –нарицательное Наташа собственное. Нарицательных имен у вас может быть несколько но запомните собственное не изменно. подобрать собственное имя.
44646. Собственные и нарицательные имена существительные 21.1 KB
  Орг момент Отгадаем ребус: отец Какие орфограммы встречаются в этом слове Можем ли мы ее проверить Значит это слово словарное. на какие вопросы оно отвечает на какие две большие группы мы можем поделить и. сущ Как отличить Еще на какие чем они отличаются Какие группы слов мы пишем с заглавной буквы фронтальный опрос и. Прочитай1 ученик устно какие группы слов могут быть собственными.
44648. Имена существительные - названия явлений природы и качеств людей 20.63 KB
  Имена существительные названия явлений природы и качеств людей. Тип урока: комбинированный ФОУД: фронтальная индивидуальная групповая Дидактическая цель: создать условия для систематизации знаний учащихся по теме Имя существительное Задачи: 1.Образовательные: познакомиться с лексическим значением групп существительных; находить отличительные особенности групп; учиться использовать их в своей речи; 2. О какой части речи это стихотворение Что такое имя существительное им.
44649. Единственное и множественное число имен существительных 19.43 KB
  Образовательные: систематизировать и углубить знания об именах существительных единственного и множественного числа; учить находить имена существительные единственного и множественно числа в тексте и подбирать их самостоятельно; учить классифицировать имена существительные единственного и множественного числа; отрабатывать умения изменять имена существительные по числам. Даны существительные в единственном числе преобразовать в существительные множественного числа. Даны существительные во множественном числе преобразовать в...
44650. Единственное и множественное число имен существительных 19.98 KB
  Минутка чистописания: пропишем ее три раза 1 человек у доски 1 букву с комментированием пропишем соединение буквы т с буквой о в тетради 3 раза1 человек на доске с комментированием запишем все словарное слово в н. мн ед ч по смыслу умения находить слова мн ед ч и правильно определят чила имен сущ. доске записаны слова сосны с_сна хлеба хле_ грибы гри_ травы тр_ва горы г_ра Что заметили По какому признаку слова записаны в два столбика Запишем первое слово из второго столбика1ч к доске ост. Как мы ее можем проверить С...