fonctions de maths
Publié : dim. 18/févr./2007 11:20
pour commencer des fonctions de trigo
ensuite la fonction exponentielle (j'ai galéré mais c'est NICKEL =)
des fonctions de probabilités (étrangement ca a été super simple =)
Le modulo version nombres réels
Des fonctions d'arrondis (je sais y'a Round...)
et des fonctions à part sur la représentation des nombres réels
Les fonctions sont relativement optimisées (chui pas un pro de l'asm...) dans la mesure où je fais appel le moins possible aux variables réelles. Elles ne sont utilisées qu'au chargement...
Dri
Code : Tout sélectionner
Procedure.f WrapValue(Angle.f) ;[0, 2Pi[
;charge 2Pi
!FLDPI
!FADD st, st
;charge Angle
!FLD dword [p.v_Angle]
;calcule WrapValue
!FPREM
!FSTP st1
;l'angle est négatif ?
!FLDZ
!FCOMP
!FNSTSW ax
!TEST ah, $41
!JNE l_wrapvalue_ok
;on lui ajoute 2Pi
!FLDPI
!FADD st, st
!FADDP
wrapvalue_ok:
!RET 4
EndProcedure
Procedure.f ATan2(y.f, x.f) ;[-Pi, Pi[
!FLD dword [p.v_y]
!FLD dword [p.v_x]
!FPATAN
!RET 8
EndProcedure
Procedure.f ATanFull(y.f, x.f) ;[0, 2Pi[
!FLD dword [p.v_y]
!FLD dword [p.v_x]
!FPATAN
;l'angle est négatif ?
!FLDZ
!FCOMP
!FNSTSW ax
!TEST ah, $41
!JNE l_atanfull_ok
;on lui ajoute 2Pi
!FLDPI
!FADD st, st
!FADDP
atanfull_ok:
!RET 8
EndProcedure
Code : Tout sélectionner
Procedure.f Exp(x.f)
Protected i.l
!NewCW equ p.v_i+0
!OldCW equ p.v_i+2
;charge x sans s'occuper du signe
!FLD dword [p.v_x]
!FABS
;n = x / Log(2)
!FLDLN2
!FDIVR st0, st1
;récupère le CW
!FNSTCW word [NewCW]
!FNSTCW word [OldCW]
;crée le CW pour arrondi par défaut
!AND word [NewCW], $F3FF
!OR word [NewCW], $0400
!FLDCW word [NewCW]
;n = Floor(n)
!FRNDINT
;restore le CW
!FLDCW word [OldCW]
;u = x - n * Log(2)
!FXCH
!FLD st1 ;charge n
!FLDLN2
!FMULP
!FSUBP
;m = Exp(u)
!FLD1 ;m
!FLD1 ;t
!MOV dword [p.v_i], 1
exp_loop:
;tant que t > 0
!FLDZ
!FCOMP
!FNSTSW ax
!TEST ah, $40
!JNE l_exp_end_loop
;t * u / i
!FMUL st0, st2
!FIDIV dword [p.v_i]
;i + 1
!INC dword [p.v_i]
;m + t
!FADD st1, st0
!JMP l_exp_loop
exp_end_loop:
!FSTP st0 ;retire t
!FSTP st1 ;retire u
!FSCALE ;r = m * Pow(2, n)
!FSTP st1 ;retire n
;si x négatif
!TEST dword [p.v_x], $80000000
!JE l_exp_end
;r = 1.0 / r
!FLD1
!FDIVRP
exp_end:
!ADD esp, 4
!RET 4
EndProcedure
Code : Tout sélectionner
Procedure.d Factorial(n.l) ;n!
;si n négatif factorielle est indéfinie
!TEST dword [p.v_n], $80000000
!JNE l_factorial_end
!FLD1 ;le résultat dans st0
factorial_loop:
;tant que n > 1
!CMP dword [p.v_n], 1
!JLE l_factorial_end
;calcule la factorielle
!FIMUL dword [p.v_n]
!DEC dword [p.v_n]
!JMP l_factorial_loop
factorial_end:
!RET 4
EndProcedure
Procedure.d Permutations(n.l, p.l) ;A(n, p)
;si n négatif pas d'arrangements
!TEST dword [p.v_n], $80000000
!JNE l_permutations_end
;si p négatif pas d'arrangements
!TEST dword [p.v_p], $80000000
!JNE l_permutations_end
;si n inférieur à p pas d'arrangements
!MOV eax, dword [p.v_n]
!CMP eax, dword [p.v_p]
!JL l_permutations_end
!FLD1 ;résultat dans st0
!SUB eax, dword [p.v_p] ;eax = n - p
permutations_loop:
;tant que n > eax
!CMP dword [p.v_n], eax
!JE l_permutations_end
;calcule les arrangements
!FIMUL dword [p.v_n]
!DEC dword [p.v_n]
!JMP l_permutations_loop
permutations_end:
!RET 8
EndProcedure
Procedure.d Combinations(n.l, p.l) ;C(n, p)
;si n négatif pas de combinaisons
!TEST dword [p.v_n], $80000000
!JNE l_combinations_end
;si p négatif pas de combinaisons
!TEST dword [p.v_p], $80000000
!JNE l_combinations_end
;si n inférieur à p pas de combinaisons
!MOV eax, dword [p.v_n]
!CMP eax, dword [p.v_p]
!JL l_combinations_end
!FLD1 ;résultat dans st0
;si p > n/2
!SHR eax, 1
!CMP eax, dword [p.v_p]
!JG l_combinations_loop
;on prend n - p à la place de p
!MOV eax, dword [p.v_n]
!SUB eax, dword [p.v_p]
!MOV dword [p.v_p], eax
combinations_loop:
;tant que p > 0
!CMP dword [p.v_p], 0
!JLE l_combinations_end_loop
;calcule les combinaisons
!FIMUL dword [p.v_n]
!FIDIV dword [p.v_p]
!DEC dword [p.v_n]
!DEC dword [p.v_p]
!JMP l_combinations_loop
combinations_end_loop:
!FRNDINT
combinations_end:
!RET 8
EndProcedure
Code : Tout sélectionner
Procedure.f Mod(x.f, y.f) ;x % y
!FLD dword [p.v_x]
!FLD dword [p.v_y]
!FPREM
!FSTP st1
!RET 8
EndProcedure
Code : Tout sélectionner
Procedure.f Ceil(Value.f)
Protected CW.l
!NewCW equ p.v_CW+0
!OldCW equ p.v_CW+2
;récupère le CW
!FNSTCW word [OldCW]
!FNSTCW word [NewCW]
;crée le CW pour arrondi par excès
!AND word [NewCW], $F3FF
!OR word [NewCW], $0800
!FLDCW word [NewCW]
;calcule l'arrondi
!FLD dword [p.v_Value]
!FRNDINT
;restore le CW
!FLDCW word [OldCW]
!ADD esp, 4
!RET 4
EndProcedure
Procedure.f Floor(Value.f)
Protected CW.l
!NewCW equ p.v_CW+0
!OldCW equ p.v_CW+2
;récupère le CW
!FNSTCW word [OldCW]
!FNSTCW word [NewCW]
;crée le CW pour arrondi par défaut
!AND word [NewCW], $F3FF
!OR word [NewCW], $0400
!FLDCW word [NewCW]
;calcule l'arrondi
!FLD dword [p.v_Value]
!FRNDINT
;restore le CW
!FLDCW word [OldCW]
!ADD esp, 4
!RET 4
EndProcedure
Code : Tout sélectionner
Procedure.f Significand(Value.f)
!FLD dword [p.v_Value]
!FXTRACT
!FSTP st1
!RET 4
EndProcedure
Procedure.f Exponent(Value.f)
!FLD dword [p.v_Value]
!FXTRACT
!FSTP st0
!RET 4
EndProcedure
Procedure.f Scale(Significand.f, Exponent.f)
!FLD dword [p.v_Exponent]
!FLD dword [p.v_Significand]
!FSCALE
!FSTP st1
!RET 8
EndProcedure
Dri
