Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как посчитать EXP(x) в мат. сопроцессоре? Экспонента от вещественного аргумента. 
:(
    Опции темы
St. Andrew
Дата 16.11.2005, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 142
Регистрация: 28.3.2005
Где: Санкт-Петербург

Репутация: 1
Всего: 8



Добрый день! У меня возникла трудность при программировании математического сопроцессора. Нужно посчитать e в степени х , т.е. аналог функции exp(x) или просто - экспоненту. Проблема в том, что аргумент экспоненты - вещественное число, поэтому посчитать в лоб итерационным методом не выходит. Подскажите, пожалуйста, формулу!

P.S. Мне кажется, что туплю. smile Неужели для экспоненты в мат. сопроцессоре нет стандартной функции? smile
--------------------
Оглянитесь вокруг! В мире так много прекрасного!
PM MAIL WWW ICQ   Вверх
Chingachguk
Дата 17.11.2005, 01:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 11
Всего: 18



Вроде бы нету. Я скомпиллировал код в tp7 и BC 3.10 примерно следующего содержания:

d:=exp(2.76); или d=exp(2.76);

Далее я зашел в экзешник в отладчике (use td.exe), потрассировал код до вызова exp. Вот как к примеру это выглядит в СИ (после входа в int 3E, что видимо является подпрограммой вычислений на сопроцессоре и у обоих языков сделано одинаково):

// Начало кода
¦ printf("\nStart...");
¦ d= exp(2.67);
¦ return;

// Входим в режим ассемблера (ALT+F7)
¦ cs:092CDD06A000 fld qword ptr[00A0]
¦ cs:0930 83EC08 sub sp,0008
¦ cs:0933 9B wait
¦ cs:0934 DD5EAA fstp qword ptr[bp-56]
¦ cs:0937 90 nop
¦ cs:0938 9B wait
¦ cs:0939 9A4A0E305A call far _exp
¦ cs:093E 83C408 add sp,0008

; Заходим в _exp (опять F7 или ALT+F7)
¦_exp
¦ cs:0E4A55 push bp
¦ cs:0E4B 8BEC mov bp,sp
¦ cs:0E4D 56 push si
¦ cs:0E4E 9B wait
¦ cs:0E4F DD4606 fld qword ptr[bp+06]
¦ cs:0E52 B8FF7F mov ax,7FFF
¦ cs:0E55 23460C and ax,[bp+0C]
¦ cs:0E58 3D8640 cmp ax,4086
¦ cs:0E5B 7306 jnb 0E63
¦ cs:0E5D CD3EFA90 int 3E

; ...Там еще подпрограмма... (skipped)
; Заходим в int 3E (ALT+F7)
¦ cs:02179B wait
¦ cs:0218 D9EA fldl2e
¦ cs:021A B101 mov cl,01
¦ cs:021C 9B wait
¦ cs:021D D9C9 fxch st(1)
¦ cs:021F 9B wait
¦ cs:0220 D9E5 fxam
¦ cs:0222 55 push bp
¦ cs:0223 8BEC mov bp,sp
¦ cs:0225 8D66FC lea sp,[bp-04]
¦ cs:0228 9B wait
¦ cs:0229 DD7EFC fstsw word ptr[bp-04]
¦ cs:022C E303 jcxz 0231

Как видно, все начинается с команды fld2e (загрузить log2(e)), далее какие-то циклы...

smile

Best wishes,
Chingachguk








--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
St. Andrew
Дата 18.11.2005, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 142
Регистрация: 28.3.2005
Где: Санкт-Петербург

Репутация: 1
Всего: 8



Chingachguk, я почитал книжку Юрова, он там как раз приводит хорошую формулу:
e^x=2^(x*log2(e)) То есть ты прав и вся эта канитель как раз начинается с команды fldl2e.
Я набросал на примере вышеуказанного автора кусок программы на сопроцессоре во встроенном АСМЕ в Паскале, вроде бы должно все компилироваться, но компилятор почему-то выводит на последней строке программы end. ошибку 161 "Code generation error" Раньше с этим не сталкивался.... smile Не подскажешь, из-за чего подобная ошибка может возникать? Все-таки в самом коде никаких ошибок компилятор не находит!

Моя вставка должна вычислить значение ф-ии tan(x+1)/(e^x) при 0<x<e/2 Изначально х меняется от 0 до 649, а при умножении на gradus - делится на 492, попадая в заданный диапазон. Переменные: a=1 (word), x (word), y (double).
Код

fild x
fmul gradus
fiadd a
DB 0D9h, 0FEH   ;fsin
fild x
fmul gradus
fiadd a
DB 0D9h, 0FFH   ;fcos
fdiv
fstp y            ;вытащили из стека tan(x+1)

fild x             ; загружаем аргумент
fmul gradus
fldl2e             
fmul               ;получаем степень двойки
fld1
fcom           ; сравниваем степень с 1
fstsw ax     
sahf
jnc @m2     ; если степень < 1

fld1           ;если степень > 1, то делим у на 2 и уменьшаем степень двойки на 1
fiadd a
fld y
fdivr
fstp y

@m2:       ; если степень < 1
fsub
f2xm1   ;высчитываем 2^....-1
fld1
fadd    ;компенсируем единичку

fld y    
fdivr     ;в вершине стека tan(x+1)/e^x


Никак не пойму, почему компилятор Паскаля при наличии этого куска выдает ошибку в конце программы.... smile

Это сообщение отредактировал(а) St. Andrew - 18.11.2005, 14:28
--------------------
Оглянитесь вокруг! В мире так много прекрасного!
PM MAIL WWW ICQ   Вверх
Chingachguk
Дата 18.11.2005, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 11
Всего: 18



Цитата
{$N+}
{$G+}
const
  a: word = 1;
var
  x: word;
  y,gradus: double;
begin
asm
fild x
fmul gradus
fiadd a
DB 0D9h, 0FEH  { fsin }
fild x
fmul gradus
fiadd a
DB 0D9h, 0FFH  { fcos }
fdiv
fstp y          { вытащили из стека tan(x+1) }

fild x          { загружаем аргумент }
fmul gradus
fldl2e           
fmul            { получаем степень двойки }
fld1
fcom          { сравниваем степень с 1 }
fstsw ax   
sahf
jnc @m2    { если степень < 1 }

fld1        { если степень > 1, то делим у на 2 и уменьшаем степень двойки на 1 }
fiadd a
fld y
fdivr
fstp y

@m2:      { если степень < 1 }
fsub
f2xm1  { высчитываем 2^....-1 }
fld1
fadd    { компенсируем единичку }

fld y   
fdivr    { в вершине стека tan(x+1)/e^x }
end;

end.



--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
St. Andrew
Дата 18.11.2005, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 142
Регистрация: 28.3.2005
Где: Санкт-Петербург

Репутация: 1
Всего: 8



Протестировав свое творение, пришел к неутешительным выводам.... smile В общем, кусок, который считает экспоненту, работает! Проблема в том, что дальше еще имеются команды (смены знака, округления и т.д.) Они все рабочие, я многократно проверил аргументы, стек и т.д. Стало быть, проблема не в них! Но самое противное, что стоит мне только закомментировать любой кусок размером команд в 5-8 из ассемблерной вставки - все сразу начинает компилироваться и работать! Похоже, что дело в размере кода, а не в операторах... smile
Чтобы не быть голословным, привожу целиком свою программу. В действительности, она высчитывает значения ф-ии и строит график по точкам.
Код

{$N+}
{$G+}
Program grafik;
uses crt;
const e=2.73;
var
x,y2,a,c,i,b,os,mnogitel,: word;
y,gradus  : double;

begin
clrscr;

a:=1;
mnogitel:=4; {koefficient rastjagivanija po y}
b:=200;
gradus:=1/492;  {koefficient rastjagivanija po x}

asm
mov ax, 0     {vkl. grafiku}
mov al, 10h
int 10h

{mov ah, 0ch}       {вывод осей графика (закомментировал для отладки)}
{mov al, 11
mov cx, 400
mov bh, 0h
mov dx, 0
@metka1:
push cx
mov os, cx
mov dx, os
mov cx,0
int 10h
pop cx
loop @metka1

mov ah, 0ch
mov al, 11
mov cx, 639
mov bh, 0h
mov dx, 200
@metka2:
int 10h
loop @metka2 }
end;

asm
mov cx, 639   {начало цикла}
@loopx:
mov x, cx
fild x
fmul gradus
fiadd a
DB 0D9h, 0FEH  { fsin }
fild x
fmul gradus
fiadd a
DB 0D9h, 0FFH  { fcos }
fdiv
fstp y          { вытащили из стека tan(x+1) }

fild x          { загружаем аргумент }
fmul gradus
fldl2e
fmul            { получаем степень двойки }
fld1
fcom          { сравниваем степень с 1 }
fstsw ax
sahf
jnc @m2    { если степень < 1 }

fld1        { если степень > 1, то делим у на 2 и уменьшаем степень двойки на 1 }
fiadd a
fld y
fdivr
fstp y

@m2:      { если степень < 1 }
fsub
f2xm1  { высчитываем 2^....-1 }
fld1
fadd    { компенсируем единичку }

fld y
fdivr    { в вершине стека tan(x+1)/e^x }

fimul mnogitel   {растягиваем график по у}
fchs
fiadd b
frndint
fistp y2             {извлекаем округленное значение у}

mov ah, 0ch       {выводим точку на экран}
mov bh,0h
mov dx, y2
mov al, 15
int 10h
loop @loopx       

mov ah, 8
int 21h
end;
end.


У меня не компилируется. smile Все та же ошибка 161... Может Паскаль у меня битый?

Это сообщение отредактировал(а) St. Andrew - 18.11.2005, 15:39
--------------------
Оглянитесь вокруг! В мире так много прекрасного!
PM MAIL WWW ICQ   Вверх
tothilm
Дата 10.9.2022, 07:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 9.9.2022

Репутация: нет
Всего: нет




Модератор: Сообщение скрыто.

PM MAIL   Вверх
Jarrats
Дата 7.10.2022, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 6.10.2022

Репутация: нет
Всего: нет



Based on this, the Department of Drug Administration DDA controls the maximum retail price MRP of those 117 pharmaceutical products in the Nepalese market 17 <a href=http://buylasixon.com/>when to hold lasix</a> TGF beta1 suppresses apoptosis via differential regulation of MAP kinases and ceramide production
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для начинающих"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm для начинающих | Следующая тема »


 




[ Время генерации скрипта: 0.1223 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.