PureBasic

Forums PureBasic
Nous sommes le Ven 06/Déc/2019 9:35

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 54 messages ]  Aller à la page 1, 2, 3, 4  Suivante
Auteur Message
 Sujet du message: Astuces et codes utiles sur les Mathématiques
MessagePosté: Lun 05/Sep/2005 17:15 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 13/Fév/2004 0:57
Messages: 3702
Vous pouvez poster ici tous les codes et infos concernant l'utilisation des mathématiques sous Pure Basic.

:)


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Lun 05/Sep/2005 19:23 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 25/Aoû/2005 22:59
Messages: 445
Localisation: 974
aller je commence par "Soche caches toi"

SOH CAH TOA


Sinus = Coté opposé / Hypotenuse
Cosinus = Coté adjacent / Hypotenuse
Tagente = Coté opposé / Coté adjacent

_________________
Quelques manoucheries : I can't give you anything but love / Stompin' at decca


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Lun 05/Sep/2005 19:27 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 25/Aoû/2005 22:59
Messages: 445
Localisation: 974
un autre truc tout con :

Chiffre négatif = ennemis
chiffre positif = amis

les amis de mes amis sont mes amis : un chiffre positif * un chiffre positif = un chiffre positif

marche avec toutes les combinaisons...

_________________
Quelques manoucheries : I can't give you anything but love / Stompin' at decca


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Mar 06/Sep/2005 6:58 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 23/Jan/2004 18:10
Messages: 2527
Les fonctions de maths sont relativelent gourmandes en performances... Quelques situations où on peut éviter de s'en servir ou s'en servir sans en abuser... (j'édite au fur et à mesure)

Toutes les fonctions sont compatibles avec EnableExplicit


comparer une valeur à une racine carrée
Code:
a.f = 2.0
b.f = 4.0

If a = Sqr(b)
  Debug "ca fonctionne"
EndIf

If (a * a) = b
  Debug "ca fonctionne aussi"
EndIf

ca peut être utile dans les comparaisons de distances. si a et b deux distances, et a2 et b2 les carrés (puissance 2) respectifs alors :
a < b <=> a2 < b2
a = b <=> a2 = b2 etc...
il n'est pas utile de calculer les distances complètement pour les comparaisons... la racine encore une fois est obsolete.


complément trigo : convertir des angles
Code:
#RadToDeg = 180.0 / #PI
#RadToGrd = 200.0 / #PI
#DegToRad = #PI / 180.0
#DegToGrd = 200 / 180.0
#GrdToRad = #PI / 200.0
#GrdToDeg = 180 / 200.0

Macro RadToDeg(Rad)
  ((Rad) * #RadToDeg)
EndMacro

Macro RadToGrd(Rad)
  ((Rad) * #RadToGrd)
EndMacro

Macro DegToRad(Deg)
  ((Deg) * #DegToRad)
EndMacro

Macro DegToGrd(Deg)
  ((Deg) * #DegToGrd)
EndMacro

Macro GrdToRad(Grd)
  ((Grd) * #GrdToRad)
EndMacro

Macro GrdToDeg(Grd)
  ((Grd) * #GrdToDeg)
EndMacro

Vive les macros et la constante #PI :D


complément trigo : Sécante, Cosécante, Cotangente
Code:
Macro Sec(Angle)
  (1.0 / Cos(Angle))
EndMacro

Macro Csc(Angle)
  (1.0 / Sin(Angle))
EndMacro

Macro Cot(Angle)
  (1.0 / Tan(Angle))
EndMacro

ne me demandez pas d'exemple d'utilisation :P


complément trigo : Arc Tangent
Code:
Procedure.d ATan2(dy.d, dx.d)
  !FLD qword [p.v_dy]
  !FLD qword [p.v_dx]
  !FPATAN
  ProcedureReturn
EndProcedure

Procedure.d ATanFull(dy.d, dx.d)
  Protected Angle.d

  If dx = 0.0
    If dy > 0 : Angle = #PI / 2.0
    Else : Angle = 3.0 * #PI / 2.0
    EndIf
  ElseIf dy = 0.0
    If dx > 0 : Angle = 0.0
    Else : Angle = 2.0 * #PI
    EndIf
  Else
    !FLD    qword [p.v_dy]
    !FLD    qword [p.v_dx]
    !FPATAN
    !FSTP   qword [p.v_Angle]
  EndIf

  If Angle < 0.0
    Angle + (2.0 * #PI)
  EndIf

  ProcedureReturn Angle
EndProcedure

OpenWindow(0, 0, 0, 400, 400, "ATanFull", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)

Repeat
  If StartDrawing( WindowOutput(0) )
   
   
    Box(0, 0, 400, 400, #White)
   
    DrawingMode(#PB_2DDrawing_Outlined|#PB_2DDrawing_Transparent)
   
    Circle(200, 200, 150, #Black)
    Line(20, 200, 360, 0)
    Line(200, 20, 0, 360)
   
    DrawText(352, 200, "0")
    DrawText(184, 350, "90")
    DrawText( 22, 184, "180")
    DrawText(202,  20, "270")
    DrawText(352, 184, "360")
   
    x = WindowMouseX(0)
    y = WindowMouseY(0)
   
    If x>=0 And y>=0 And x<400 And y<400
     
      dx = x - 200
      dy = y - 200
     
      angle.f = RadToDeg( ATan(dy / dx) )
      DrawText(0,  0, "ATan : " + StrF(angle))
     
      angle.f = RadToDeg( ATan2(dy, dx) )
      DrawText(0, 16, "ATan2 : " + StrF(angle))
     
      angle.f = RadToDeg( ATanFull(dy, dx) )
      DrawText(0, 32, "ATanFull : " + StrF(angle))
     
      LineXY(200, 200, x, y, #Red)
    EndIf
   
    StopDrawing()
  EndIf
Until WaitWindowEvent() = #PB_Event_CloseWindow

avec en prime un exemple pour illustrer... plus précis que l'arc tangent simple (-Pi/2 < angle < Pi/2 je crois)


Plus Grand Diviseur Commun et Plus Petit Multiple Commun
Code:
Procedure GCD(a.l, b.l)
  Protected c.l
 
  If a And b
    While b   
      c = a % b
      a = b
      b = c
    Wend
   
    If a < 0
      a = -a
    EndIf
  Else
    a = 0
  EndIf
 
  ProcedureReturn a
EndProcedure

Procedure LCM(a.l, b.l)
  Protected c.l
 
  If a And b
    c = a * b / GCD(a, b)
    If c < 0
      c = -c
    EndIf
  EndIf
 
  ProcedureReturn c
EndProcedure

Debug GCD( 12,  15)
Debug GCD( 12, -15)
Debug GCD(-12,  15)
Debug GCD(-12, -15)

Debug "---"

Debug LCM( 12,  15)
Debug LCM( 12, -15)
Debug LCM(-12,  15)
Debug LCM(-12, -15)

Si si ca peut servir :P


connaître le signe d'un nombre
Code:
Macro Sgn(Number)
  ((Number > 0 Or #False) - (Number < 0 Or #False))
EndMacro

Debug Sgn(-5)
Debug Sgn(-0)
Debug Sgn( 5)

Debug Sgn(-5.0)
Debug Sgn(-0.0)
Debug Sgn( 5.0)

Nan franchement ca non-plus c'est pas inutile :lol:


probabilités : Factorielle, Combinaisons, Arrangements
Code:
Procedure.d Factorial(n.l)
  Protected r.d
 
  If n >= 0
    r = 1
   
    While n > 1
      r * n
    Wend
  EndIf
 
  ProcedureReturn r
EndProcedure

Procedure.d Combinations(n.l, p.l)
  Protected r.d
 
  If n >= 0 And p >= 0
   
    If n >= p
      r = 1.0
     
      If p > n / 2
        p = n - p
      EndIf
     
      While p > 0
        r * n / p
        n - 1
        p - 1
      Wend
     
      If r - Round(r, 0) > 0.5
        r + 1
      EndIf
    EndIf
   
  EndIf
 
  ProcedureReturn Round(r, 0)
EndProcedure

Procedure.d Permutations(n.l, p.l)
  Protected r.d
 
  If n >= 0 And p >= 0
   
    If n >= p
      r = 1.0
     
      p = n - p
     
      While n > p
        r * n
        n - 1
      Wend
    EndIf
   
  EndIf
 
  ProcedureReturn r
EndProcedure

Je retourne des nombres réels au lieu d'entiers (ca peut parasiter à 10^-9 environ) parce que ça grimpe très vite... pour vous convaincre voici un exemple avec une version récursive des combinaisons. Elle met chez moi plus de 10 secondes à fournir le même résultat, très gros comparé aux valeurs n et p.

Code:
Procedure.l C(n.l, p.l)
  Protected r
 
  If n < 0 Or p < 0
    r = 0
  ElseIf p = 0 Or n = p
    r = 1
  Else
    r = C(n-1, p-1) + C(n-1, p)
  EndIf
 
  ProcedureReturn r
EndProcedure

Debug C(25, 15)


J'ai ajouté l'arrondi pour les combinaisons ^^, et voila un petit exemple
(je chercherais un moyen plus propre d'arrondir...)
Code:
n = 50

For p = 0 To n
  Debug "C(" + Str(n) + ", " + Str(p) + ") = " + StrD(Combinations(n, p), 20)
Next p


Dri


Dernière édition par Dr. Dri le Dim 11/Fév/2007 16:38, édité 18 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Mar 06/Sep/2005 11:12 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 25/Aoû/2005 22:59
Messages: 445
Localisation: 974
ah oué pas con

_________________
Quelques manoucheries : I can't give you anything but love / Stompin' at decca


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Mar 06/Sep/2005 11:20 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 25/Aoû/2005 22:59
Messages: 445
Localisation: 974
un truc aussi pour éviter de faire des multiplications ou divisions (gourmand aussi en perf)

pour multiplier un nombre par 2
plutot que de faire
resultat = n * 2

il faut mieux faire :
resultat = shl(n, 1)

un shl déplace tout les bits du nombre de pas indiqué vers la gauche, ce qui équivaut à une multiplication et c'est beaucoup plus rapide

shl(n, 2) = multplication par 4
shl(n, 3) = multiplication par 8
shl(n, 4) = multiplication par 16
shl(n,x) = multiplication par 2^x

même principe pour les divisions avec shr

astuce : si vous voulez multiplier par 5, faites un shl(n,2) et ajoutez n

(ps : je n'ai pas encore regardé dans PB si les fonction shl et shr existent...si elle n'existent pas on peut toujour le faire en assembleur dans le code PB)

_________________
Quelques manoucheries : I can't give you anything but love / Stompin' at decca


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Mar 06/Sep/2005 11:30 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 16/Mai/2004 17:50
Messages: 505
Localisation: Bayonne (64)
Le mieux serait de regarder avant de poster.

Le compilateur effectue une addition pour les multiplications par deux et un décalage pour les multiplications par des puissnaces de deux autres.

Ce qui est parfaitement optimisé.

_________________
Mon avatar reproduit l'image de 4x1.8m présentée au 'Salon international du meuble de Paris' en janvier 2004, dans l'exposition 'Shades' réunisant 22 créateurs autour de Matt Sindall. L'original est un stratifié en 150 dpi.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Mar 06/Sep/2005 14:18 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 23/Jan/2004 18:10
Messages: 2527
a + a est plus rapide que a << 1 ? c'est vraiment de l'optimisation ?
Code:
#i = 1000000000

b.l = 1

a = ElapsedMilliseconds()
For i = 0 To #i
  b + b
Next i
a = ElapsedMilliseconds() - a
MessageRequester("*2 version +", Str(a), 16)

a = ElapsedMilliseconds()
For i = 0 To #i
  b << 1
Next i
a = ElapsedMilliseconds() - a
MessageRequester("*2 version <<", Str(a), 16)

sans debugger bien sûr
j'obtiens 15000+ et 14500+

Dri :!:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Mar 06/Sep/2005 15:56 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 16/Mai/2004 17:50
Messages: 505
Localisation: Bayonne (64)
Ce n'est pas une différence significative en fait.

Selon le fait de lancer le même test à différents moments et de placer les deux séquences dans un sens ou dans l'autre on obtient des résultats instables.

De fait l'addition d'un registre sur lui-même prend exactement le même temps si j'en crois les specs Intel, soit un cycle. Mais le rendu dans le cadre d'un prog qui est lancé par l'OS n'est pas forcément aussi précis.

Dans tous les cas le shift d'un bit n'est pas plus rapide.

_________________
Mon avatar reproduit l'image de 4x1.8m présentée au 'Salon international du meuble de Paris' en janvier 2004, dans l'exposition 'Shades' réunisant 22 créateurs autour de Matt Sindall. L'original est un stratifié en 150 dpi.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Mar 06/Sep/2005 18:14 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 23/Jan/2004 18:10
Messages: 2527
Avoir un processeur AMD ca peut jouer ?

Dri


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Mar 06/Sep/2005 19:49 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 16/Mai/2004 17:50
Messages: 505
Localisation: Bayonne (64)
@Dr. Dri,

Non le principe de basculement d'un registre sur lui-même est invariant chez tous les fondeurs.

Et il n'y a aucun gain non plus à tenter de jouer sur deux registres, en raison du temps de copie d'un registre sur un second, qui prend au minimum le même temps que la ré-injection du contenu d'un registre sur lui-même.

On en restera toujours à un cycle minimum quelque soit le chemin que l'on prenne.

_________________
Mon avatar reproduit l'image de 4x1.8m présentée au 'Salon international du meuble de Paris' en janvier 2004, dans l'exposition 'Shades' réunisant 22 créateurs autour de Matt Sindall. L'original est un stratifié en 150 dpi.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Mer 07/Sep/2005 7:56 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 25/Aoû/2005 22:59
Messages: 445
Localisation: 974
Citation:
Le compilateur effectue une addition pour les multiplications par deux et un décalage pour les multiplications par des puissnaces de deux autres.


ah bon ?? ah ben je ne savais pas...

_________________
Quelques manoucheries : I can't give you anything but love / Stompin' at decca


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Ven 09/Sep/2005 17:24 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 16:22
Messages: 1092
Localisation: 76
Résolution d'un trinôme... Ça peut toujours servir.
Code:
Procedure.s trinome(a, b , c)
  d = b*b - 4*a*c
  If d < 0
    ProcedureReturn "d < 0"
  ElseIf d = 0
    ProcedureReturn Str(-b/2*a)
  Else
    ProcedureReturn Str((-b-Sqr(d))/2*a)+"|"+Str((-b+Sqr(d))/2*a)
  EndIf
EndProcedure

_________________
Heis Spiter, webmaster du site http://www.heisspiter.net
Développeur principal et administrateur du projet Bird Chat
Parti courir au bonheur du dév. public et GPL :D


Dernière édition par Heis Spiter le Ven 09/Sep/2005 17:32, édité 1 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Ven 09/Sep/2005 17:27 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 23/Jan/2004 18:10
Messages: 2527
mon astuce sur les racines carrées ca vaut aussi pour les carrés
remplace le Pow(b, 2) par b*b

Dri :0:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: Ven 09/Sep/2005 17:31 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 16:22
Messages: 1092
Localisation: 76
Bien vu ;), b*b est plus rapide ! C'est pas :0:, mais :10:

_________________
Heis Spiter, webmaster du site http://www.heisspiter.net
Développeur principal et administrateur du projet Bird Chat
Parti courir au bonheur du dév. public et GPL :D


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 54 messages ]  Aller à la page 1, 2, 3, 4  Suivante

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 3 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