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
