Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.11.2009, 21:26   #11
airyashov
Форумчанин
 
Регистрация: 02.04.2008
Сообщений: 358
По умолчанию

подумать времени не хватает, но алгоритм приведенный http://programmersforum.ru/showpost....69&postcount=6
рабочий? это общий случай если именно функцию нужно x^(1/3) это должно быть проще
неплохо пишу на ассемблере для 80х86
icq: 3(один)7748666
mail: airyashov(а)inbox.ru
airyashov вне форума Ответить с цитированием
Старый 19.11.2009, 12:10   #12
NiCola999
Не
Участник клуба
 
Регистрация: 29.10.2009
Сообщений: 1,456
По умолчанию

а по какой формуле в том исходнике на 1 стр вычисляется степень? я знаю только одну формулу...

exp(ln(x)/n) 1/n- степень

exp = sum(k=0,n) x^k / k! (ряд Тейлора)
n достаточно взять 15

дело в том, что мы не проходили написание функций на чистом асм, мы пишем прототип внешней функции в сишном файле, а код функции в асм файле. Загрузка аргументов функции на стек и операции над ними. Все задания должны выполняться именно так...
попробую в выходные реализовать exp(ln(x)/3) с помощью ряда Тейлора, если нет никаких приближенных формул для exp(x)...

Последний раз редактировалось NiCola999; 19.11.2009 в 12:20.
NiCola999 вне форума Ответить с цитированием
Старый 19.11.2009, 16:54   #13
airyashov
Форумчанин
 
Регистрация: 02.04.2008
Сообщений: 358
По умолчанию

короче вот родился код
это написано для положительных чисел >8 для остального нужно просто написать условия и все будет ок, на отрицательность и на значение степени <1, выделение целой части тоже упрощено (будет округление нужно настроить SR), если время найдется подправлю
Код:
  var x,y,s:double;
      i:LongWord;
begin
  x:=10;
  s:=1/3;
  asm
    fld s
    fld x
    fyl2x
    fist i
    mov ecx,i
    mov eax,2
    sub ecx,1
    shl eax,cl
    fild i
    mov i,eax
    fsubp st(1),st(0)
    f2xm1
    fld1
    faddp st(1),st(0)
    fild i
    fmulp st(1),st(0)
    fstp y
  end;
неплохо пишу на ассемблере для 80х86
icq: 3(один)7748666
mail: airyashov(а)inbox.ru

Последний раз редактировалось airyashov; 19.11.2009 в 17:10.
airyashov вне форума Ответить с цитированием
Старый 19.11.2009, 17:42   #14
NiCola999
Не
Участник клуба
 
Регистрация: 29.10.2009
Сообщений: 1,456
По умолчанию

Цитата:
это написано для положительных чисел >8 для остального нужно просто написать условия и все будет ок, на отрицательность и на значение степени <1, выделение целой части тоже упрощено (будет округление нужно настроить SR), если время найдется подправлю
если бы было всё так просто. Не нужно выделять целую часть, корень должен вычисляться на любых числах, в разумных пределах
NiCola999 вне форума Ответить с цитированием
Старый 19.11.2009, 21:01   #15
airyashov
Форумчанин
 
Регистрация: 02.04.2008
Сообщений: 358
По умолчанию

Цитата:
Сообщение от NiCola999 Посмотреть сообщение
если бы было всё так просто. Не нужно выделять целую часть, корень должен вычисляться на любых числах, в разумных пределах
ну так добавьте это не сложно, будет время Я поправлю код

зашел в тупик, что должна делать команда
FSCALE если в стеке st(0)=1 st(1)=1
неплохо пишу на ассемблере для 80х86
icq: 3(один)7748666
mail: airyashov(а)inbox.ru

Последний раз редактировалось airyashov; 19.11.2009 в 22:42.
airyashov вне форума Ответить с цитированием
Старый 20.11.2009, 23:52   #16
airyashov
Форумчанин
 
Регистрация: 02.04.2008
Сообщений: 358
По умолчанию

вот окончательный код
Код:
const s:Double=1/3;
var x,y:Double;
    i:LongWord;
    j:Integer;
    st:WideString;
    cr:word;
begin
  for j:=-10 to 10 do begin
  x:=j;
  asm
    fld x
    ftst
    fstsw ax
    not ax
    test ax,0100000000000000b // проверка на 0
    jz @zero

    fabs
    fld s
    fxch
    fyl2x
    fld st(0)
    fstcw cr
    mov dx,cr
    or cr,0000110000000000b
    fldcw cr
    frndint
    mov cr,dx
    fldcw cr
    fsub st(1),st(0)
    fistp i

    mov edx,1
    mov ecx,i
    shl edx,cl

    f2xm1
    fld1
    faddp st(1), st(0)

    test ax,00000000100000000b // проверка на <0
    jnz @non
    neg edx
@non:
    mov i,edx
    fild i
    fmulp st(1),st(0)
@zero:
    fstp y
  end;
    st:=st+FloatToStr(x)+' '+FloatToStr(y)+#13+#10;
  end;
  ShowMessage(st);
end.
неплохо пишу на ассемблере для 80х86
icq: 3(один)7748666
mail: airyashov(а)inbox.ru

Последний раз редактировалось airyashov; 21.11.2009 в 00:26.
airyashov вне форума Ответить с цитированием
Старый 21.11.2009, 01:29   #17
NiCola999
Не
Участник клуба
 
Регистрация: 29.10.2009
Сообщений: 1,456
По умолчанию

я не очень понимаю, по какому алгоритму ты считаешь корень, если не сложно обьясни на языке речи или например на языке си/с++, а не на асм, просто мне тяжеловато читать код =)

Последний раз редактировалось NiCola999; 21.11.2009 в 01:37.
NiCola999 вне форума Ответить с цитированием
Старый 21.11.2009, 09:27   #18
airyashov
Форумчанин
 
Регистрация: 02.04.2008
Сообщений: 358
По умолчанию

Цитата:
Сообщение от NiCola999 Посмотреть сообщение
я не очень понимаю, по какому алгоритму ты считаешь корень, если не сложно обьясни на языке речи или например на языке си/с++, а не на асм, просто мне тяжеловато читать код =)
вот математика
неплохо пишу на ассемблере для 80х86
icq: 3(один)7748666
mail: airyashov(а)inbox.ru
airyashov вне форума Ответить с цитированием
Старый 21.11.2009, 12:07   #19
NiCola999
Не
Участник клуба
 
Регистрация: 29.10.2009
Сообщений: 1,456
По умолчанию

переписал под свой асм

z = 1/3 (log2(x))

x^(1/3) = 2^(z-(int)z) * 2^(int)z

Код:
tmp: .double 0.333333333333333
_cbrt:
     fld qword ptr tmp
     fld qword ptr [esp+4]

     fyl2x         ;z
     fld st(0)    ;copy z
     frndint      ;round(z)
     fsubp        ;u = z-(int)z
     f2xm1       ;2^u-1
     fld1          
     faddp  # 2^z-(int)z ;  u2 = 2^u-1+1
     

     fld qword ptr tmp # y
     fld qword ptr [esp+4]  # x

     fyl2x
     frndint   ; (int) z

     f2xm1   ; 2^(int)z  - 1
     fld1      
     faddp    ;2^(int)z  - 1+1     (*)
     fmulp    ; x^(1/3)

     ret
2^(int)z я считаю как

(2^(int)z)-1 + 1
f2xm1
fld1
faddp

все бы хорошо, но например при x=27
z = 1/3*1.58 = 1.59
(int)z = 2
когда я считаю 2^(int)z
f2xm1
получается 2 !!! а должно быть 3
(2^2)-1 = 4-1 = 3
почему так ?

можно как-то сделать сдвигом это делать, но я не понял...

Последний раз редактировалось NiCola999; 21.11.2009 в 16:38.
NiCola999 вне форума Ответить с цитированием
Старый 21.11.2009, 23:16   #20
NiCola999
Не
Участник клуба
 
Регистрация: 29.10.2009
Сообщений: 1,456
По умолчанию

задача решена, спасибо
NiCola999 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
работа с FPU NiCola999 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 14 04.11.2009 00:01