Advertisement
Guest User

Untitled

a guest
Jun 24th, 2017
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. void algorithm12ryad(double mass[], double x, int n, double epsilon, double d)
  2. {  
  3.     int i = 1;
  4.     int two = 2;
  5.     int one = 1;
  6.     int maxsumn = 1000;
  7.     __asm {
  8.         mov ecx, n
  9.         mov eax, maxsumn
  10.         inc eax
  11.         mov ebx, mass
  12.         xor edx, edx
  13.         xor si, si
  14.         finit
  15.         fld epsilon             // st4  epsilon точность
  16.         fld1                    // st3  1 для хранение константы 1
  17.         fld x                   // st2  x
  18.         fld1                    // st1  1 для хранения суммы n-1 членов
  19.         fldz                    // st0  0 для вычислений
  20.         fldz                   
  21.         fincstp                 // st7 0
  22. bigcycle:
  23. sumcycle:
  24.         fiadd i                 // st(0) = i         команда сопроцессора, для суммирования регистра с целочисленным значением fadd для вещественного.
  25.         fadd st(0), st(3)       // st(0) = i + 1
  26.         fmul st(0), st(2)       // (i+1) x^i  a i-ый элемент
  27.         fincstp
  28.         fchs                    // изменим знак суммы. таким образом получим при i чёт - (i+1)^i x сложится, а при неч вычтется в конце программы поменяем знак результата.
  29.         fdecstp
  30.         fadd st(1), st(0)       // добавим к сумме в st(1), st(0) то есть(i+1) x^2
  31.  
  32.         inc [i]                 // инкремент i
  33.         not si                  // флаг изменения знака для чётного количества элементов нужно изменять, для нечётного нет.
  34.         cmp eax, i              // сравнение (eax, i)
  35.         jbe exit1               // (n<=i)?
  36.        
  37.        
  38.         //fadd st(0), st(1)     // копируем в st(0) сумму
  39.         fabs                    // модуль числа st(0) = abs(st(0))
  40.         fucom st(4)             // сравнение с вершиной стека значения источника.  если дописать p
  41.         fstsw   ax              // С помощью команды "FSTSW AX" программа может переписать содержимое регистра состояния сопроцессора в регистр AX центрального процессора.
  42.         sahf                    // содержимое регистра AH можно переписать в регистр флагов центрального процессора при помощи команды SAHF. можно использовать стандартные команды перехода je, ja, etc.
  43.        
  44.         fsub st(0), st(0)       // обнуление вершины
  45.         fincstp                 // уменьшает указатель стека на 1
  46.         fincstp
  47.         fmul st(0), st(0)       // x*x на каждом шаге
  48.         fdecstp
  49.         fdecstp                 // увеличивает указатель стека на 1
  50.  
  51.         jbe exit1
  52.        
  53.         jmp sumcycle
  54. exit1:
  55.         fincstp
  56.        
  57.         cmp si, 0
  58.         je nochange
  59.         fchs
  60.         nochange:
  61.         fst QWORD PTR [ebx + edx*8]         //команда сохранения значения из вершины стека в память, не сдвигая стек. для вещественного.
  62.        
  63.         fsub st(0), st(0)
  64.         fadd st(0), st(2)
  65.         fincstp
  66.         fsub st(0), st(0)
  67.         fadd x
  68.         fadd d
  69.         fst x
  70.         fdecstp
  71.         fdecstp
  72.  
  73.         inc edx
  74.         mov [i], 1
  75.         xor si, si
  76.     loop bigcycle
  77.     }
  78. }
  79.  
  80. void algorithm12func(double mass[], double x, int n, double d) {
  81.     _asm {
  82.         finit
  83.         mov ecx, n          // в ecx n = количество повторений или длина массива
  84.         mov ebx, mass       // в ebx адрес массива для результирующих значений
  85.         xor edx, edx        // в edx номер текущего элемента массива
  86.         fld d               // загрузка x
  87.         fld1                // загружает единицу
  88.     bigcycle:
  89.         fld x               // загружает x st(0) = x
  90.         fadd st(0), st(1)   // x(st(0)) = x(st(0)) + 1(st(1))
  91.         fmul st(0), st(0)   // (x+1)^2
  92.         fdivr st(0), st(1)  // st(0) = st(1)/st(0) так как есть постфикс xxxxr по умолчанию st(0) = st(0)/st(1)
  93.  
  94.         fstp QWORD PTR [ebx + edx*8] // записываем в массив получившиеся значения.
  95.         fld x                        // загружаем x для прибавления шага d
  96.         fadd st(0), st(2)            // прибавляем шаг
  97.         fstp x                       // fstp - выгружает данные в память, извлекая вершину стека.
  98.         inc edx                      // индекс массива.
  99.         loop bigcycle
  100.     }
  101. }
  102.  
  103. double RootMeanSquareError(double *mass1, double *mass2, int n)
  104. {
  105.     double result = 0;
  106.     _asm {
  107.         mov ecx, n
  108.         mov eax, mass1
  109.         mov ebx, mass2
  110.         xor edx, edx
  111.         finit
  112.         fldz
  113. cycle:
  114.             fld QWORD PTR [ebx + edx*8]
  115.             fld QWORD PTR [eax + edx*8]
  116.             fsub st(0), st(1)               // mass2[i] - mass1[i]
  117.             fmul st(0), st(0)               // (mass2[i] - mass1[i])^2
  118.             fadd st(2), st(0)               // st(2) - сумма += (mass2[i] - mass1[i])^2
  119.             fstp result                     // дибильная операция по извлечению верхушки стека. дибильная, потому что ещё и записывает в память.
  120.             fstp result
  121.             inc edx
  122.         loop cycle
  123.         fild n                              // загружаем n
  124.         fdivr st(0), st(1)                  // summ/n b помещаем в st(0)
  125.         fsqrt                               // sqrt(st(0))
  126.         fst result
  127.     }
  128.     return result;
  129. }
  130.  
  131. int _tmain(int argc, _TCHAR* argv[])
  132. {
  133.     int leng = 0;
  134.     double *mass1 = new double[leng];
  135.     double *mass2 = new double[leng];
  136.     double x = 0.120796;
  137.     double epsilon = 0.05;
  138.     double step = 0.05;
  139.     while (1)
  140.     {
  141.         printf("n = ");
  142.         scanf("%i", &leng);
  143.         printf("\nx = ");
  144.         scanf("%f", &x);
  145.         printf("\nepsilon = ");
  146.         scanf("%f", &epsilon);
  147.         printf("\nstep = ");
  148.         scanf("%f", &step);
  149.         algorithm12func(mass2, x, leng, step);
  150.         algorithm12ryad(mass1, x, leng, epsilon, step);
  151.         printf("\nYour result:\n");
  152.         for(int i = 0; i < leng; i++)
  153.         {
  154.             printf("ryad(%f) - %i - %e\n", x + i*step, i+1, mass1[i]);
  155.             printf("func(%f) - %i - %e\n\n", x + i*step, i+1, mass2[i]);
  156.         }
  157.         printf("RootMeanSquareError %e\n\n", RootMeanSquareError(mass1, mass2, leng)); getch();
  158.     }
  159.     return 0;
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement