Bonjour,
Je vous propose un nouvel élément à utiliser : Comment déterminer la parité d'un nombre
Comment déterminer la parité d'un nombre.
Qu'en pensez-vous ?
Bonjour,
Je vous propose un nouvel élément à utiliser : Comment déterminer la parité d'un nombre
Comment déterminer la parité d'un nombre.
Qu'en pensez-vous ?
pour des entiers il est plus simple et performant de faire :
car en binaire seul le premier bit est égal à 1 donc impair, donc si ce bit est à zéro, le chiffre est paire.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 function estPair(a: integer): boolean; begin result := (a and 1) = 0; end;
tout cela se passe par un masque ET sur bit 0x01
Ta méthode :
génère l'assembleur suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 function EstPair(const VotreChiffre :integer):boolean; var i :integer; begin result := false; i := VotreChiffre div 2; if i * 2 = VotreChiffre Then result := True; end;
Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 xor ecx,ecx mov edx,eax sar edx,1 jns lp0 adc edx,$00 lp0: add edx,edx cmp eax,edx jnz lp1 mov cl,$01 lp1:
soit 9 instruction, deux conditions jump, une addition, une comparaison, un ou exclusif, un décalage de bit .... tout ça pour ... savoir si N est pair ou impair.
même en optimisant :
on génère en assembleur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 function EstPair(const VotreChiffre :integer):boolean; begin result := ((VotreChiffre div 2) * 2) = VotreChiffre; end;
Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 mov edx,eax sar edx,1 jns lp0; adc edx,$00 lp0: add edx,edx cmp eax,edx setz al
-2 instructions... pourtant on a supprimer pas mal de trucs.
Donc non, la méthode est "à connaitre" mais à ne pas mettre en production.
voici l'assembleur généré par le "ET 1" :
Code : Sélectionner tout - Visualiser dans une fenêtre à part result := (votreChiffre and 1) = 0;
Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 test al,$01 setz al
deux instructions.
[ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
Ma messagerie n'est pas la succursale du forum... merci!
Bonjour,
Et avec if not odd(MonEntier) then MonEntierEstPair n'est ce pas kif-kif ?
A+.![]()
génére sur D2009 ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part not odd(N)
Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 and al,$01 xor al,$01
mais (N and 1) xor 1 n'est pas une expression booléenne !
pour la rendre booléenne il faudrait l'ecrire :
boolean((N and 1) xor 1)
Ce qui oblige a faire un transtypage, qui ne change rien à l'assembleur généré, certes, mais qui fait de l'écriture en plus pour le développeur.
par contre je crois que sur les anciennes version de delphi Odd etait une fonction donc risque de donner 4 instruction voir 5 au lieu de 2.
autre avantage, c'est que Odd n'est pas forcement dispo sur tout les langages (php, javascript par exemple), la solution AND= fonctionne donc sur tous :
php : ($N & 1 == 0)
javascript/c/perl : (N & 1 == 0)
python : (N and 1 == 0)
delphi : ((N and 1) = 0)
asm : test al,$1; setz al;
facile à retenir et à implémenter.
la solution du XOR peut par contre être pratique pour faire de la condition un sélecteur d'index dans un tableau ou liste. puisque le resultat par défaut est un entier.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 const ABool : array[boolean] of TColor = ( clWhite, clBlack ); AInt : array[0..3] of TColor = (clRed, clBlue, clGreen, clYellow); begin Color1 := ABool[ (N and 1) = 0]; Color2 := AInt[ I + (N and 1 xor 1) ]; end;
[ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
Ma messagerie n'est pas la succursale du forum... merci!
Bonjour,
A Dr Who :Odd fonction [de Delphi1 et au moins jussqu'à D5] ... risque de donner 4 instructions voir 5 au lieu de 2.
Ok, merci, ... mais qu'est-ce-que c'est bien compliqué quand on n'y pige rien en Asm.
A+.![]()
Oh non, je disais ça aussi au départ, mais en fait c'est trés trés simple.
faut juste s'y mettre un peu.
Du moins tant qu'on comprend que, plus il y a d'instructions plus ça mets du temps et donc, moins il y en as, moins ça mets de temps, c'est déjà ça.
par exemple, si tu fait inc(I), tu obtient une seule instructions.
Et les instructions de ce type, sur un registre 32bit, tu peux considérer que tu peux en 1 seconde en faire autant que de Ghz du CPU (à quelques milliers prés).
en gros, CPU 1.8Ghz -> 1 seconde = 1 800 millions d'incrémentations possible (théorique), CPU 3Ghz -> 1 seconde = 3 milliard d'incrémentations possible.
exemple
théoriquement, il faut 1 seconde pour exécuter cette boucle hors instructions nécessaires à la boucle (1 seconde également).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 var I : LongWord; for N := 0 to GetCpuFrequency-1 do inc(I);
soit à peu prés entre 1 et 3 secondes maximum.
Les opérations sur les flottant (hors type Single) sont quasiment le double ou quadruple de temps.
Single est trés rapide car 32bits, ce n'est pas pour rien qu'il est préféré à Double dans la GDI+, OpenGL et DirectX.
[ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
Ma messagerie n'est pas la succursale du forum... merci!
Partager