Comment convertir une macro en C en PureBasic ?

Sujets variés concernant le développement en PureBasic
comtois
Messages : 5191
Inscription : mer. 21/janv./2004 17:48
Contact :

Comment convertir une macro en C en PureBasic ?

Message par comtois »

en fait c'est extrait d'un code en C++ , mais je ne crois pas que ça fasse de différence pour ce qui me concerne.

j'ai ce bout de code

Code : Tout sélectionner

typedef unsigned int uint32;
#define in(a) ((uint32&) a)

;Ici on calcul x,y et z , on obtient ainsi 3 nombres flottants
x.f=un calcul quelconque
y.f=un calcul quelconque
z.f=un calcul quelconque

;Et enfin on appelle la macro 
Resultat.b = (( in(z)& ~(in(x) | in(y)) ) & 0x80000000)
Je sais que le compilo va remplacer la macro par le code qui lui correspond .

J'aurai au final

Code : Tout sélectionner

Resultat.b = (( ((uint32&) z)& ~(((uint32&) x) | ((uint32&) y)) ) & 0x80000000)
Déjà , est-ce que ça vous semble correct ?
Admettons que oui , alors maintenant j'expose mon problème , c'est qu'en fait je ne comprends pas ce que fait cette macro.

Si je comprends bien typedef permet de définir un type personnalisé.
En l'occurence il s'agirait ici d'un entier non signé.
le symbole & est utilisé pour donner l'adresse d'une variable.

en fait l'association uint32& permet de créer une référence ?
mais une référence sur quoi ?
est-ce que ça revient à écrire ça ?

Code : Tout sélectionner

Resultat.b = (((uint32 &z)& ~((uint32 &x) | ((uint32 &y)) & 0x80000000)
bon là j'avoue je suis paumé , si quelqu'un pouvait démêler la ficelle :?
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message par Chris »

Ben déjà, "uint32" c'est le type "Unsigned Integer 32 bits", "Entier non signé 32 bits" donc, selon moi, tu peux le virer.

Par contre, le "&", c'est utilisé comment, en C++ ?
Sami
Messages : 51
Inscription : mar. 01/nov./2005 21:13
Localisation : Savigny-Sur-Orge

Message par Sami »

Dans ce cas il me semble que le caractére & a deux utilisations. Dans le TypeDef c'est bien l'adresse de ta variable que tu stocke dans un entier de 32 bit non signé.
Par contre dans ton expression c'est l'opérateur Bitwise AND.
Plus d'infos sur la syntaxe du C/C++ ici
comtois
Messages : 5191
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

c'est bon, je crois que j'ai compris

si j'ai

Code : Tout sélectionner

int i=0;
int &ri=i;
ri=ri+1;
ça permet de manipuler i via ri.
c'est l'équivalent d'un pointeur sur i

alors finalement , ma macro revient à faire ça ?

Code : Tout sélectionner

Resultat.b = (((int(z))& ~((int(x)) | ((int(y)) & 0x80000000)
c'est trop simple, il doit y avoir encore un truc qui m'échappe !
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
comtois
Messages : 5191
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

mouais c'est toujours pas clair .

je viens de lire un truc sur le transtypage en C:

Code : Tout sélectionner

int i=5, j=2 ;
((float) i)/j
apparemment en C++ c'est autrement , mais il est tard , et je ne vois pas d'exemple correspondant à mon cas, dans la doc que j'ai ça parle de transtypage dynamique, statique , de réinterprétation des données :?

bon ça ressemble à du transtypage mon affaire ?
pour passer d'une valeur en flottant à une valeur en entier non signé ?
c'est ça ?
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Non, là, le casting ne sert que pour pouvoir faire les opérations booléennes, si je ne me trompe pas. En clair, il demande au compilateur de considérer les valeurs comme des valeurs entières, même si ce sont des flottants. Il n'y a pas de conversion! Le & sert effectivement à référencer la valeur en mémoire.

La macro effectue un certain nombre d'opérations booléennes directement sur les variables telles qu'elles sont en mémoire, sans conversion, rend négatif le signe, et met ça dans un octet (ça je comprends pas trop)

Je poste un exemple dès que possible.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Voilà, pour tester

Code : Tout sélectionner

x.f=-1
y.f=-1
Gosub test

x.f=-1
y.f=0
Gosub test

x.f=0
y.f=-1
Gosub test

x.f=0
y.f=1
Gosub test

x.f=1
y.f=0
Gosub test

x.f=1
y.f=1
Gosub test

End


test:
	Debug "x : "+RSet(Hex(x),8,"0")+" ou "+StrF(x)
	Debug "y : "+RSet(Hex(y),8,"0")+" ou "+StrF(y)
	
	;Et enfin on appelle la macro
	z=-1
	Resultat.l = ( ( PeekL(@z) & ~( PeekL(@x) | PeekL(@y) ) ) & $80000000)
	Resultat2.b=Resultat
	Debug "z : "+RSet(Hex(z),8,"0")+" ou "+StrF(z,2)
	Debug "Resultat : "+RSet(Hex(Resultat),8,"0")+"  "+RSet(Hex(Resultat2),8,"0")
	
	z=0
	Resultat.l = ( ( PeekL(@z) & ~( PeekL(@x) | PeekL(@y) ) ) & $80000000)
	Resultat2.b=Resultat
	Debug "z : "+RSet(Hex(z),8,"0")+" ou "+StrF(z,2)
	Debug "Resultat : "+RSet(Hex(Resultat),8,"0")+"  "+RSet(Hex(Resultat2),8,"0")	

	z=1
	Resultat.l = ( ( PeekL(@z) & ~( PeekL(@x) | PeekL(@y) ) ) & $80000000)
	Resultat2.b=Resultat
	Debug "z : "+RSet(Hex(z),8,"0")+" ou "+StrF(z,2)
	Debug "Resultat : "+RSet(Hex(Resultat),8,"0")+"  "+RSet(Hex(Resultat2),8,"0")
	
	Debug ""

	Return

End
comtois
Messages : 5191
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

merci pour la réponse ,je regarderai ça ce soir , à tête reposée .

voila la fonction complète, le but c'est de déterminer si un point se trouve dans un triangle.J'avais fait une fonction pour ça , mais en 2D , faudrait que je la transforme un peu pour la 3D , et ensuite je voulais comparer la différence de vitesse entre la mienne et celle ci.
Below is a function that determines if a point is inside a triangle or not. This
is used in the collision detection step. Thanks to Keidy from Mr-Gamemaker
who posted this particular version of the function in a little competition we
held about who could post the fastest one.

Code : Tout sélectionner

typedef unsigned int uint32;
#define in(a) ((uint32&) a)
bool checkPointInTriangle(const VECTOR& point,
const VECTOR& pa,const VECTOR& pb, const VECTOR& pc)
{
VECTOR e10=pb-pa;
VECTOR e20=pc-pa;
float a = e10.dot(e10);
float b = e10.dot(e20);
float c = e20.dot(e20);
float ac_bb=(a*c)-(b*b);
VECTOR vp(point.x-pa.x, point.y-pa.y, point.z-pa.z);
float d = vp.dot(e10);
float e = vp.dot(e20);
float x = (d*c)-(e*b);
float y = (e*a)-(d*b);
float z = x+y-ac_bb;
return (( in(z)& ~(in(x)|in(y)) ) & 0x80000000);
}
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Ok, c'est bien ça. Apparemment la macro renvoie TRUE (-1) si x et y sont positifs (>=0) et z négatif (<0).
Sami
Messages : 51
Inscription : mar. 01/nov./2005 21:13
Localisation : Savigny-Sur-Orge

Message par Sami »

Attention le C et le C++ c'est trés différent même certains mots clef sont commun.
comtois
Messages : 5191
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Finalement je voulais à tout prix la tester cette procédure , alors je l'ai écrite comme ça :

Code : Tout sélectionner

Procedure TestPointDansTriangle1(*point.s_Vecteur, *pa.s_Vecteur, *pb.s_Vecteur, *pc.s_Vecteur)
   Define.s_Vecteur e10, e20, vp 
   Define.f a, b, c, ac_bb, d, e, x, y, z
   
   SoustractionVecteur(e10, *pb, *pa)
   SoustractionVecteur(e20, *pc, *pa)
   
   a = ProduitScalaire(e10, e10)
   b = ProduitScalaire(e10, e20)
   c = ProduitScalaire(e20, e20)
   ac_bb = (a*c)-(b*b)
   SoustractionVecteur(vp, *point, *pa)
   d = ProduitScalaire(vp, e10)
   e = ProduitScalaire(vp, e20)
   x = (d*c)-(e*b)
   y = (e*a)-(d*b)
   z = x+y-ac_bb
   ProcedureReturn ((PeekL(@z)& ~(PeekL(@x)|PeekL(@y))) & $80000000)
EndProcedure
ça fonctionne très bien , je n'ai pas encore vraiment comparé avec la procédure que j'utilisais , juste un test rapide ,et le gain serait de 20% environ.A confirmer cependant avec d'autres tests.

J'ai encore d'autres algos à tester, décidément ça prend du temps rien que pour calculer si un point se trouve dans un triangle !

PS :
Je ne comprends pas la nuance qu'il y a en C++ d'écrire

Code : Tout sélectionner

VECTOR e20=pc-pa;
Ou

Code : Tout sélectionner

VECTOR vp(point.x-pa.x, point.y-pa.y, point.z-pa.z);

Moi je l'ai écrit exactement de la même manière, est-ce qu'il y a une subtilité qui m'échappe ?

[EDIT]
Tiens , je n'avais pas fait attention mais djes avait déjà donné la solution :)

Code : Tout sélectionner

( ( PeekL(@z) & ~( PeekL(@x) | PeekL(@y) ) ) & $80000000) 
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Répondre