Разложение sh(x) в ряд

Низкоуровневое программирование портов, микроконтроллеров и т.д.

Модератор: Andy

Аватара пользователя
Alex_Burn
Сообщения: 147
Зарегистрирован: 13 апр 2007, 17:49
Контактная информация:

Ну, в общем, дошел я до следующего
[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]

Но работает не корректно. Может я чего не верно делаю?
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Результат сравнения будет в регистре состояния FPU, структура его схожа с регистром флагов, поэтому выполнять сравнение можно так

Код: Выделить всё

fcom precision
fstsw ax
sahf
jg @cycle   ; если ST(0) больше точности, то переход
It's a long way to the top if you wanna rock'n'roll
Аватара пользователя
Alex_Burn
Сообщения: 147
Зарегистрирован: 13 апр 2007, 17:49
Контактная информация:

При замене фрагмента

Код: Выделить всё

fcom precision 
jl @cycle      
на фрагмент

Код: Выделить всё

fcom precision  
fstsw ax
sahf
jg @cycle
программа виснет. Может быть значение функции необходимо возращать как-то по-другому?
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

От многих проблем избавляет отладка, посмотрите, почему код не выходит из цикла. Возможно необходимо изменить условие на противоположное
It's a long way to the top if you wanna rock'n'roll
Аватара пользователя
Alex_Burn
Сообщения: 147
Зарегистрирован: 13 апр 2007, 17:49
Контактная информация:

Отладка? Но я же пытаюсь сделать задание в С++.
Сишный экзешник тоже можно продебаггить?
Под противоположным условием ты имеешь ввиду jle @cycle?
Я пробовал, но результат получается неверным и точность на него никак не влияет.
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

&quot писал(а):Отладка? Но я же пытаюсь сделать задание в С++.
Сишный экзешник тоже можно продебаггить?
Конечно, вообще легко, любой ЕХЕ-шник - если уж используете асм, то без дебагера - что суп вилкой жрать.
&quot писал(а):Под противоположным условием ты имеешь ввиду jle @cycle?
Я пробовал, но результат получается неверным и точность на него никак не влияет.
Я просто путаюсь иногда, что чего больше должно быть. Поскольку дебагера нет, то на-вскидку могу только сказать что после команды проверки jg(jle) идет fst function, но на тот момент на стеке фпу будут два числа - для нормального завершения функции там ничего не должно быть. Попробуйте заюзать пошаговую отладку, и посмотреть где там чего не срастается - или ехе в студию - посмотрю.
It's a long way to the top if you wanna rock'n'roll
Аватара пользователя
Alex_Burn
Сообщения: 147
Зарегистрирован: 13 апр 2007, 17:49
Контактная информация:

Прикрепляю архив с EXE:

prog1 - c jg
prog2 - c jle

Я смотрел в TD 3.2, ничего вразумительного не увидел.
airyashov
Сообщения: 441
Зарегистрирован: 02 ноя 2007, 10:31

Устал следить за вашим диалогом, вот код, компилил на 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;
}
Аватара пользователя
Alex_Burn
Сообщения: 147
Зарегистрирован: 13 апр 2007, 17:49
Контактная информация:

Спасибо большое за код.
А зачем нужна строка test ax, 01000010100000000b?
airyashov
Сообщения: 441
Зарегистрирован: 02 ноя 2007, 10:31

Alex_Burn писал(а):Спасибо большое за код.
А зачем нужна строка test ax, 01000010100000000b?

Это сравнение соотвествует условию st(0)>e, т.е цикл выполняется пока оно истина
Ответить