PureBasic

Forums PureBasic
Nous sommes le Sam 25/Mai/2013 15:12

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 6 messages ] 
Auteur Message
 Sujet du message: fonctions de maths
MessagePosté: Dim 18/Fév/2007 11:20 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 23/Jan/2004 18:10
Messages: 2527
pour commencer des fonctions de trigo
Code:
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

ensuite la fonction exponentielle (j'ai galéré mais c'est NICKEL =)
Code:
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

des fonctions de probabilités (étrangement ca a été super simple =)
Code:
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

Le modulo version nombres réels
Code:
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

Des fonctions d'arrondis (je sais y'a Round...)
Code:
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

et des fonctions à part sur la représentation des nombres réels
Code:
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


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 :D


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 18/Fév/2007 11:46 
Hors ligne
Avatar de l’utilisateur

Inscription: Lun 26/Avr/2004 0:40
Messages: 12957
et voila c'est pompé Coloré et envoyé sur le Forum des codes FR

http://michel.dobro.free.fr/forum/

:D

_________________
Image


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 18/Fév/2007 12:22 
Hors ligne

Inscription: Jeu 26/Fév/2004 15:36
Messages: 1191
Localisation: France
nickel Image

_________________
"Qui baise trop bouffe un poil." P. Desproges


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Lun 19/Fév/2007 19:04 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 23/Jan/2004 18:10
Messages: 2527
le PGCD ^_^ (merci PB pour le code ASM du modulo)
Code:
Procedure GCD(a.l, b.l)
  !MOV  eax, dword [p.v_a]
  !MOV  ebx, dword [p.v_b]
 
  gcd_loop:
 
  ;tant que b <> 0
  !CMP ebx, 0
  !JE  l_gcd_end
   
  ;calcule le PGCD
  !CDQ
  !IDIV ebx
  !MOV  eax, ebx
  !MOV  ebx, edx
 
  !JMP l_gcd_loop
 
  gcd_end:
 
  !RET 8
EndProcedure


Dri


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Sam 24/Fév/2007 21:30 
Rajoute des fonctions pour les calculs matricielles ^^ et fait en une bonne lib :wink:


Haut
  
 
 Sujet du message:
MessagePosté: Lun 24/Sep/2007 12:26 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 29/Juin/2007 17:50
Messages: 1901
Merci Dr Dri. C'est excellent ces fonctions. J'avais besoin d'Atanfull.


Haut
 Profil  
 
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 6 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 0 invités


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye