Страница 1 из 3

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

Добавлено: 03 апр 2008, 14:27
Alex_Burn
Здравствуйте, уважаемые участники форума. Взываю к Вашей помощи.
Задание следующее:

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

В принципе, математически разложить данную функцию в данный ряд не очень сложно.
Ряд Маклорена является частным случаем след. ряда (см. рис 1).
Если в ряде 1 принять a=0, то получится след. ряд (см. рис 2).
Таким образом, применительно к заданной функции ряд примет вид (см. рис 3).

В теории все просто, но как это реализовать я не представляю.
Позвольте поделиться с Вами мыслями:
наверно, нужно каждый сгенерированный член ряда нужно сравнивать с введенной с клавиатуры точностью, пока не будет сгенерирован член, точность которого больше введенной точности. А потом произвести сложение членов.

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

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

Добавлено: 03 апр 2008, 15:07
airyashov
сопроцессор математический вам в помощь, а ввод чисел вещественных написать придется

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

Добавлено: 03 апр 2008, 19:37
Alex_Burn
airyashov писал(а):сопроцессор математический вам в помощь, а ввод чисел вещественных написать придется
Понимаю, но от этого легче не становится... :-)

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

Добавлено: 03 апр 2008, 22:51
Alex_Burn
Ребят, ну подскажите пожалуйста с реализацией, а то этот асм меня просто убъет! У вас же очень много опыта. Задача для меня просто невероятно сложная.

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

Добавлено: 03 апр 2008, 22:59
airyashov
не часто просто приходится работать с FPU, ну Вы начните хотябы, алгоритм опишите как собираетесь решать, на вводе не заморачивайтесь, пусть х будет константа для начала.

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

Добавлено: 04 апр 2008, 11:28
somewhere
Первый член суммы - это Х, все остальные получаются путем умножение предыдущего на Х^2 и делением на следущие составляющие факториала. Определим переменные X, fact (в начале цикла = 2) Т.е. выглядит примерно так

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

fld x      ; загрузим на стек первый член
fld st(0) ; скопируем его, в ST(1) будет храниться сумма
     @cycle:
fmul x   ; получаем след. член, умножаем пред. на Х^2
fmul x   
fdiv fact  ; делим на один из элементов факториала, поскольку
fld fact    ; в знаменателе факториал идет с шагом 2, 
fld1        ; то делим еще и на следущий элемент
fadd       ; здесь добавляем 1
fdiv st(1), st(0) ; и делим, результат в st(1)
fld1           ; теперь перейдем к след. элементу факториала
fadd          ; добавим еще 1
fdiv st(1), st(0) ; и опять делим, результат в st(1)
fstp fact     ; и сохраним текущий множитель факториала, теперь в St(0) - текущий элемент последов.
fadd st(1), st(0) - а в St(1) стала сумма
Потом проверяем, если в St(0) значение меньше чем заданная точность, то выходим из цикла, если нет - то идем к @cycle.

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

Добавлено: 06 апр 2008, 16:51
Alex_Burn
2 somewhere
Спасибо большое за код! Значит после прохождения цикла в st(1) - сумма, а в st(0) - последний элемент последовательности, или как?


Ребят, ну у меня особо мыслей по ввода-вывода нет. Я тут перерыл почти весь рунет по этому вопросу, нашел 2 программы, но во всех прогах ловятся баги.
Я выложу их здесь в архиве. Я бы выложил кодом, но они довольно большие.

Ребята, помогите пожалуйста.

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

Добавлено: 07 апр 2008, 11:30
somewhere
Значит после прохождения цикла в st(1) - сумма, а в st(0) - последний элемент последовательности, или как?
Да
Ребят, ну у меня особо мыслей по ввода-вывода нет.
Попробуй мой код

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

;=============================================
; Input  : DS:SI - Offset to string
; Output : ST(0) - Number
;          No error checking to safe code
;          Negative numbers supported
;          "+" sign not supported
;
StrToFloat proc near
pusha
push es

movzx cx, [si+1]
inc cx
add si, 2
mov di, si
mov ax, ds
mov es, ax
cld
mov bx, cx
mov al, '.'
repnz scasb
sub bx, cx
sub bx, 2
dec di
movzx cx, [si-1]
fld1
sub dh, dh
cmp [si], byte ptr '-'
jnz @stf_positive
mov dh, 1
dec cx
dec bx
inc si
	@stf_positive:
or bx, bx
jz @stf_floatpart
fmul Ten
dec bx
jmp @stf_positive
	@stf_floatpart:
fstp @STF_Multiplier
fldz
	@stf_loop:
cmp si, di
jz @stf_point
movzx ax, byte ptr [si]
sub al, 30h
mov @stf_digit, ax
fild @stf_digit
fmul @STF_Multiplier
fadd
fld @STF_Multiplier
fdiv Ten
fstp @STF_Multiplier
	@stf_point:
inc si
dec cx
jnz @stf_loop
cmp dh, 1
jnz @stf_exit
fchs
	@stf_exit:
pop es
popa
ret
@STF_Multiplier dd ?
@STF_Digit      dw ?
StrToFloat endp

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

Добавлено: 11 апр 2008, 21:30
Alex_Burn
Здравствуйте. Извиняюсь, что давно не заходил.

2 somewhere:

Спасибо огромное за код!

Но у меня к тебе такой вопрос

Я решил поэксперементировать, и попробовать использовать твой код из поста #6 в качестве ассемблерной вставки в языке С++. Что-то типа этого.

[syntax='C++']
//---------------------------------------------------------------------------
#include<math.h>
#include<iostream.h>
#pragma hdrstop

//---------------------------------------------------------------------------
#pragma argsused
float arg;
float prec;
float y;
int fact = 2;
float sh(float x)
{
asm
{
fld x // загрузим на стек первый член
fld st(0) // скопируем его, в ST(1) будет храниться сумма
@cycle:
fmul x // получаем след. член, умножаем пред. на Х^2
fmul x
fdiv fact // делим на один из элементов факториала, поскольку
fld fact // в знаменателе факториал идет с шагом 2,
fld1 // то делим еще и на следущий элемент
fadd // здесь добавляем 1
fdiv st(1), st(0) ; и делим, результат в st(1)
fld1 // теперь перейдем к след. элементу факториала
fadd // добавим еще 1
fdiv st(1), st(0) // и опять делим, результат в st(1)
fstp fact // и сохраним текущий множитель факториала, теперь в St(0) - текущий элемент последов.
fadd st(1), st(0) // а в St(1) стала сумма
cmp ?,?
jl @cycle
...
}
return ?
}
void main()
{
cout<<"Input argument ";
cin>>arg;
cout<<endl;
cout<<"Input precision ";
cin>>prec;
cout<<endl;
y=sh(arg);
cout<<"sh(x) = "<<y;
}
[/syntax]

Поможешь доработать?
Не понятно что с чем сравнивать и как возвратить значение.

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

Добавлено: 11 апр 2008, 22:53
airyashov
cmp ?,?jl @cycle
сравнение не такое, а с помощью fpu
погрешность сравнить с st(0), а в конце извлечь из стека сумму в к-л перемнную и вернуть её как значение функции