Разложение sh(x) в ряд
Модератор: Andy
Ну, в общем, дошел я до следующего
[Syntax='C++']
double sh(float argument, float precision)
{
int factorial = 2;
double function;
asm
{
fld argument // загрузим на стек первый член
fld st(0) // скопируем его, в ST(1) будет храниться сумма
@cycle:
fmul argument // получаем след. член, умножаем пред. на Х^2
fmul argument
fdiv factorial // делим на один из элементов факториала, поскольку
fld factorial // в знаменателе факториал идет с шагом 2,
fld1 // то делим еще и на следущий элемент
fadd // здесь добавляем 1
fdiv st(1), st(0) // и делим, результат в st(1)
fld1 // теперь перейдем к след. элементу факториала
fadd // добавим еще 1
fdiv st(1), st(0) // и опять делим, результат в st(1)
fstp factorial /* и сохраним текущий множитель факториала, теперь
в St(0) - текущий элемент последов. */
fadd st(1), st(0) // а в St(1) стала сумма
fcom precision // сравниваем st(0) с точностью
jl @cycle // меньше? к cycle!!!
//fxch st(1)
fst function // Сохраняем
}
return function;
}
[/Syntax]
Но работает не корректно. Может я чего не верно делаю?
[Syntax='C++']
double sh(float argument, float precision)
{
int factorial = 2;
double function;
asm
{
fld argument // загрузим на стек первый член
fld st(0) // скопируем его, в ST(1) будет храниться сумма
@cycle:
fmul argument // получаем след. член, умножаем пред. на Х^2
fmul argument
fdiv factorial // делим на один из элементов факториала, поскольку
fld factorial // в знаменателе факториал идет с шагом 2,
fld1 // то делим еще и на следущий элемент
fadd // здесь добавляем 1
fdiv st(1), st(0) // и делим, результат в st(1)
fld1 // теперь перейдем к след. элементу факториала
fadd // добавим еще 1
fdiv st(1), st(0) // и опять делим, результат в st(1)
fstp factorial /* и сохраним текущий множитель факториала, теперь
в St(0) - текущий элемент последов. */
fadd st(1), st(0) // а в St(1) стала сумма
fcom precision // сравниваем st(0) с точностью
jl @cycle // меньше? к cycle!!!
//fxch st(1)
fst function // Сохраняем
}
return function;
}
[/Syntax]
Но работает не корректно. Может я чего не верно делаю?
Результат сравнения будет в регистре состояния FPU, структура его схожа с регистром флагов, поэтому выполнять сравнение можно так
Код: Выделить всё
fcom precision
fstsw ax
sahf
jg @cycle ; если ST(0) больше точности, то переход
It's a long way to the top if you wanna rock'n'roll
При замене фрагмента
на фрагмент
программа виснет. Может быть значение функции необходимо возращать как-то по-другому?
Код: Выделить всё
fcom precision
jl @cycle
Код: Выделить всё
fcom precision
fstsw ax
sahf
jg @cycle
От многих проблем избавляет отладка, посмотрите, почему код не выходит из цикла. Возможно необходимо изменить условие на противоположное
It's a long way to the top if you wanna rock'n'roll
Отладка? Но я же пытаюсь сделать задание в С++.
Сишный экзешник тоже можно продебаггить?
Под противоположным условием ты имеешь ввиду jle @cycle?
Я пробовал, но результат получается неверным и точность на него никак не влияет.
Сишный экзешник тоже можно продебаггить?
Под противоположным условием ты имеешь ввиду jle @cycle?
Я пробовал, но результат получается неверным и точность на него никак не влияет.
Конечно, вообще легко, любой ЕХЕ-шник - если уж используете асм, то без дебагера - что суп вилкой жрать." писал(а):Отладка? Но я же пытаюсь сделать задание в С++.
Сишный экзешник тоже можно продебаггить?
Я просто путаюсь иногда, что чего больше должно быть. Поскольку дебагера нет, то на-вскидку могу только сказать что после команды проверки jg(jle) идет fst function, но на тот момент на стеке фпу будут два числа - для нормального завершения функции там ничего не должно быть. Попробуйте заюзать пошаговую отладку, и посмотреть где там чего не срастается - или ехе в студию - посмотрю." писал(а):Под противоположным условием ты имеешь ввиду jle @cycle?
Я пробовал, но результат получается неверным и точность на него никак не влияет.
It's a long way to the top if you wanna rock'n'roll
Прикрепляю архив с EXE:
prog1 - c jg
prog2 - c jle
Я смотрел в TD 3.2, ничего вразумительного не увидел.
prog1 - c jg
prog2 - c jle
Я смотрел в TD 3.2, ничего вразумительного не увидел.
Устал следить за вашим диалогом, вот код, компилил на Borland C++Builder 6
Код: Выделить всё
#include <iostream.h>
#include <math.h>
double shx(double argument, double precision)
{
double factorial = 2;
double function;
_asm
{
fld argument
fld st(0)
cycle:
fmul argument
fmul argument
fdiv factorial
fld factorial
fld1
fadd
fdiv st(1), st(0)
fld1
fadd
//fdiv st(1), st(0) // ? «»??? nN???, ?N?????a? o st(1)
fstp factorial
fadd st(1), st(0)
fcom precision
fstsw ax
test ax, 01000010100000000b
jz cycle
fstp factorial
fstp function
}
cout<<factorial<<endl;
return function;
}
int main(int argc, char* argv[])
{
long double x=0.1,e=0.000001 ;
char ch;
cout<<shx(x,e)<<endl<<sinh(x)<<endl;
cin.get(ch);
return 0;
}
Спасибо большое за код.
А зачем нужна строка test ax, 01000010100000000b?
А зачем нужна строка test ax, 01000010100000000b?
Alex_Burn писал(а):Спасибо большое за код.
А зачем нужна строка test ax, 01000010100000000b?
Это сравнение соотвествует условию st(0)>e, т.е цикл выполняется пока оно истина