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

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

Модератор: Andy

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

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

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

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

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

Однако, как генерировать члены и куда их девать, совершенно непонятно. :confused:
В общем, уважаемые участники форума, поделитесь пожалуйста своии соображениями по поводу данного задания.
Вложения
рис 3.JPG
рис 3.JPG (5.16 КБ) 175 просмотров
рис 2.JPG
рис 2.JPG (8.38 КБ) 174 просмотра
рис 1.JPG
рис 1.JPG (7.59 КБ) 175 просмотров
airyashov
Сообщения: 441
Зарегистрирован: 02 ноя 2007, 10:31

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

airyashov писал(а):сопроцессор математический вам в помощь, а ввод чисел вещественных написать придется
Понимаю, но от этого легче не становится... :-)
Аватара пользователя
Alex_Burn
Сообщения: 147
Зарегистрирован: 13 апр 2007, 17:49
Контактная информация:

Ребят, ну подскажите пожалуйста с реализацией, а то этот асм меня просто убъет! У вас же очень много опыта. Задача для меня просто невероятно сложная.
airyashov
Сообщения: 441
Зарегистрирован: 02 ноя 2007, 10:31

не часто просто приходится работать с FPU, ну Вы начните хотябы, алгоритм опишите как собираетесь решать, на вводе не заморачивайтесь, пусть х будет константа для начала.
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Первый член суммы - это Х, все остальные получаются путем умножение предыдущего на Х^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.
It's a long way to the top if you wanna rock'n'roll
Аватара пользователя
Alex_Burn
Сообщения: 147
Зарегистрирован: 13 апр 2007, 17:49
Контактная информация:

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


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

Ребята, помогите пожалуйста.
Вложения
Input-Output.zip
(2.85 КБ) 37 скачиваний
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

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

Здравствуйте. Извиняюсь, что давно не заходил.

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]

Поможешь доработать?
Не понятно что с чем сравнивать и как возвратить значение.
airyashov
Сообщения: 441
Зарегистрирован: 02 ноя 2007, 10:31

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