Soit une variable i entière et initialisée. Je veux que i soit impair. S'il est pair, je veux le ramener à
l'impair
immédiatement inférieur. Je vois deux façons d'écrire ça : -> if(i % 2 == 0) i--; // foin des accolades, c'est un
exemple !
-> i -= 1 - (i % 2); Je me demandais laquelle des solutions est la plus rapide à
l'exécution ? la seconde, et très nettement car il n'y a pas de test et donc pas de rupture dans le flux d'instructions et donc le pipeline du proc reste bien plein. On peut d'ailleurs encore faire encore mieux: i-= 1-(i&1); qui ne fait pas de division. pour la lisibilité, tu peux faire: i-= 1-(i&1); // force i pair à l'impair inférieur
Ce n'est pas évident, les CPU modernes ont une instruction pour effectuer des MOV conditionnels, et g++ en profite sur mon athlon, voilà l'assembleur qu'il produit, dans les trois cas :
g++ -O2 -frame-omit-pointer -march=athlon-XP
// if (i % 2 == 0) i--; movl 4(%esp), %eax // %eax = i leal -1(%eax), %edx // %edx = i-1 testb $1, %al // %eax est impair ? cmove %edx, %eax // %eax = %edx
// if i -= 1 - (i % 2); movl 4(%esp), %eax movl %eax, %edx movl %eax, %ecx // shrl $31, %edx // Calcul compliqué leal (%edx,%eax), %edx // de (i % 2 == 0) andl $-2, %edx // subl %edx, %ecx leal -1(%ecx,%eax), %eax
// if i -= 1 - (i & 1); movl 4(%esp), %eax // %eax = i andl $1, %eax // %eax &= 1 addl 4(%esp), %eax // %eax += i decl %eax // %eax -=1
A mon avis, mais je n'ai pas mesuré, la première forme est la plus rapide, car le CPU peut sans doute effectuer les instructions 2 et 3 en parallèle. S'abtenir de toute optimisation manuelle est, sur cet exemple particulier et comme bien souvent, la solution la plus rapide. J'en profite pour rappeler les trois points fondamentaux de l'optimisation : 1 - Ne pas optimiser 2 - Ne pas optimiser 3 - Pour expert seulement : ne pas optimiser encore.
Cela dépend-il du compilateur ?
non, je ne crois pas qu'il y ait des compilos assez malins pour "convertir" le source de la première méthode en exécutable sans test et sans division.
Si, il y a au moins g++, icc (Intel C/C++ compiler), et sans doute la plupart des compilateurs actuels.
-- Richard
"Jean-Noël Mégoz" a écrit
Soit une variable i entière et initialisée.
Je veux que i soit impair. S'il est pair, je veux le ramener à
l'impair
immédiatement inférieur. Je vois deux façons d'écrire ça :
-> if(i % 2 == 0) i--; // foin des accolades, c'est un
exemple !
-> i -= 1 - (i % 2);
Je me demandais laquelle des solutions est la plus rapide à
l'exécution ?
la seconde, et très nettement car il n'y a pas de test et donc pas de
rupture dans le flux d'instructions et donc le pipeline du proc reste
bien plein.
On peut d'ailleurs encore faire encore mieux: i-= 1-(i&1); qui ne
fait pas de division.
pour la lisibilité, tu peux faire:
i-= 1-(i&1); // force i pair à l'impair inférieur
Ce n'est pas évident, les CPU modernes ont une instruction pour
effectuer des MOV conditionnels, et g++ en profite sur mon athlon, voilà
l'assembleur qu'il produit, dans les trois cas :
g++ -O2 -frame-omit-pointer -march=athlon-XP
// if (i % 2 == 0) i--;
movl 4(%esp), %eax // %eax = i
leal -1(%eax), %edx // %edx = i-1
testb $1, %al // %eax est impair ?
cmove %edx, %eax // %eax = %edx
// if i -= 1 - (i % 2);
movl 4(%esp), %eax
movl %eax, %edx
movl %eax, %ecx //
shrl $31, %edx // Calcul compliqué
leal (%edx,%eax), %edx // de (i % 2 == 0)
andl $-2, %edx //
subl %edx, %ecx
leal -1(%ecx,%eax), %eax
// if i -= 1 - (i & 1);
movl 4(%esp), %eax // %eax = i
andl $1, %eax // %eax &= 1
addl 4(%esp), %eax // %eax += i
decl %eax // %eax -=1
A mon avis, mais je n'ai pas mesuré, la première forme est la plus
rapide, car le CPU peut sans doute effectuer les instructions 2 et 3 en
parallèle.
S'abtenir de toute optimisation manuelle est, sur cet exemple
particulier et comme bien souvent, la solution la plus rapide. J'en
profite pour rappeler les trois points fondamentaux de l'optimisation :
1 - Ne pas optimiser
2 - Ne pas optimiser
3 - Pour expert seulement : ne pas optimiser encore.
Cela dépend-il du compilateur ?
non, je ne crois pas qu'il y ait des compilos assez malins pour
"convertir" le source de la première méthode en exécutable sans test
et sans division.
Si, il y a au moins g++, icc (Intel C/C++ compiler), et sans doute la
plupart des compilateurs actuels.
Soit une variable i entière et initialisée. Je veux que i soit impair. S'il est pair, je veux le ramener à
l'impair
immédiatement inférieur. Je vois deux façons d'écrire ça : -> if(i % 2 == 0) i--; // foin des accolades, c'est un
exemple !
-> i -= 1 - (i % 2); Je me demandais laquelle des solutions est la plus rapide à
l'exécution ? la seconde, et très nettement car il n'y a pas de test et donc pas de rupture dans le flux d'instructions et donc le pipeline du proc reste bien plein. On peut d'ailleurs encore faire encore mieux: i-= 1-(i&1); qui ne fait pas de division. pour la lisibilité, tu peux faire: i-= 1-(i&1); // force i pair à l'impair inférieur
Ce n'est pas évident, les CPU modernes ont une instruction pour effectuer des MOV conditionnels, et g++ en profite sur mon athlon, voilà l'assembleur qu'il produit, dans les trois cas :
g++ -O2 -frame-omit-pointer -march=athlon-XP
// if (i % 2 == 0) i--; movl 4(%esp), %eax // %eax = i leal -1(%eax), %edx // %edx = i-1 testb $1, %al // %eax est impair ? cmove %edx, %eax // %eax = %edx
// if i -= 1 - (i % 2); movl 4(%esp), %eax movl %eax, %edx movl %eax, %ecx // shrl $31, %edx // Calcul compliqué leal (%edx,%eax), %edx // de (i % 2 == 0) andl $-2, %edx // subl %edx, %ecx leal -1(%ecx,%eax), %eax
// if i -= 1 - (i & 1); movl 4(%esp), %eax // %eax = i andl $1, %eax // %eax &= 1 addl 4(%esp), %eax // %eax += i decl %eax // %eax -=1
A mon avis, mais je n'ai pas mesuré, la première forme est la plus rapide, car le CPU peut sans doute effectuer les instructions 2 et 3 en parallèle. S'abtenir de toute optimisation manuelle est, sur cet exemple particulier et comme bien souvent, la solution la plus rapide. J'en profite pour rappeler les trois points fondamentaux de l'optimisation : 1 - Ne pas optimiser 2 - Ne pas optimiser 3 - Pour expert seulement : ne pas optimiser encore.
Cela dépend-il du compilateur ?
non, je ne crois pas qu'il y ait des compilos assez malins pour "convertir" le source de la première méthode en exécutable sans test et sans division.
Si, il y a au moins g++, icc (Intel C/C++ compiler), et sans doute la plupart des compilateurs actuels.
-- Richard
Jean-Marc Bourguet
writes:
Ceci dit, la solution classique serait plutôt :
i &= ~1 ;
Euh, il veut que i soit impair et au plus egal a la valeur precedante. Tu le rends pair.
A+ -- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
kanze@gabi-soft.fr writes:
Ceci dit, la solution classique serait plutôt :
i &= ~1 ;
Euh, il veut que i soit impair et au plus egal a la valeur precedante.
Tu le rends pair.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Euh, il veut que i soit impair et au plus egal a la valeur precedante. Tu le rends pair.
A+ -- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Alexandre Bacquart
wrote:
i &= ~1 ;
d'après ce qu'il me semble. Solution qui risque aussi d'être la plus rapide.
Mmh, cela ne fait pas exactement ce que demande l'OP.
Déclarer i en int ou en long a-t-il un effet là-dessus ?
Là aussi, ça dépend. En revanche, avec la solution classique que j'ai présenté, il faudrait se méfier -- ça doit marcher sur une machine complémente à deux dans tous les cas, mais sur une architecture magnitude signée, il vaudrait mieux que le 1 ait le même type que i.
Moi personnellement, je pense qu'il faut toujours se méfier des manipulations de bits en C et C++.
-- Tek
kanze@gabi-soft.fr wrote:
i &= ~1 ;
d'après ce qu'il me semble. Solution qui risque aussi d'être la plus
rapide.
Mmh, cela ne fait pas exactement ce que demande l'OP.
Déclarer i en int ou en long a-t-il un effet là-dessus ?
Là aussi, ça dépend. En revanche, avec la solution classique que j'ai
présenté, il faudrait se méfier -- ça doit marcher sur une machine
complémente à deux dans tous les cas, mais sur une architecture
magnitude signée, il vaudrait mieux que le 1 ait le même type que i.
Moi personnellement, je pense qu'il faut toujours se méfier des
manipulations de bits en C et C++.
d'après ce qu'il me semble. Solution qui risque aussi d'être la plus rapide.
Mmh, cela ne fait pas exactement ce que demande l'OP.
Déclarer i en int ou en long a-t-il un effet là-dessus ?
Là aussi, ça dépend. En revanche, avec la solution classique que j'ai présenté, il faudrait se méfier -- ça doit marcher sur une machine complémente à deux dans tous les cas, mais sur une architecture magnitude signée, il vaudrait mieux que le 1 ait le même type que i.
Moi personnellement, je pense qu'il faut toujours se méfier des manipulations de bits en C et C++.
-- Tek
Alexandre Bacquart
Vincent Lascaux wrote:
-> if(i % 2 == 0) i--; // foin des accolades, c'est un exemple ! -> i -= 1 - (i % 2);
Je me demandais laquelle des solutions est la plus rapide à l'exécution ?
Moi je pense que la premiere est de loin la plus comprehensible. Et je me demande aussi si tu t'es bien demandé s'il n'y avait pas une autre partie du code à optimiser qui te ferait gagner bien plus en rapidité que les quelques instructions machines que tu vas gagner en changeant de méthode.
Quand le code en question est susceptible d'être executé des millions de fois par seconde, on ne fait pas le même raisonnement.
-- Tek
Vincent Lascaux wrote:
-> if(i % 2 == 0) i--; // foin des accolades, c'est un exemple !
-> i -= 1 - (i % 2);
Je me demandais laquelle des solutions est la plus rapide à l'exécution ?
Moi je pense que la premiere est de loin la plus comprehensible. Et je me
demande aussi si tu t'es bien demandé s'il n'y avait pas une autre partie du
code à optimiser qui te ferait gagner bien plus en rapidité que les quelques
instructions machines que tu vas gagner en changeant de méthode.
Quand le code en question est susceptible d'être executé des millions de
fois par seconde, on ne fait pas le même raisonnement.
-> if(i % 2 == 0) i--; // foin des accolades, c'est un exemple ! -> i -= 1 - (i % 2);
Je me demandais laquelle des solutions est la plus rapide à l'exécution ?
Moi je pense que la premiere est de loin la plus comprehensible. Et je me demande aussi si tu t'es bien demandé s'il n'y avait pas une autre partie du code à optimiser qui te ferait gagner bien plus en rapidité que les quelques instructions machines que tu vas gagner en changeant de méthode.
Quand le code en question est susceptible d'être executé des millions de fois par seconde, on ne fait pas le même raisonnement.
-- Tek
Jean-Marc Bourguet
"Jean-Noël Mégoz" writes:
Salut !
Soit une variable i entière et initialisée. Je veux que i soit impair. S'il est pair, je veux le ramener à l'impair immédiatement inférieur. Je vois deux façons d'écrire ça : -> if(i % 2 == 0) i--; // foin des accolades, c'est un exemple ! -> i -= 1 - (i % 2);
Je me demandais laquelle des solutions est la plus rapide à l'exécution ?
Ca va dependre du compilo et du processeur cible. Avec un processeur n'ayant d'execution conditionnelle que pour les sauts, il y a des chances pour que la deuxieme soit plus rapide. Des choix de ce genre peuvent aussi dependre du contexte et de comment le compilo arrive a associer les operations avec ce qui les entourent.
Cela dépend-il du compilateur ?
Et des parametres d'optimisation aussi.
Déclarer i en int ou en long a-t-il un effet là-dessus ?
Ca depend principalement du processeur cible. Tu peux aussi avoir des differences avec unsigned.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Soit une variable i entière et initialisée.
Je veux que i soit impair. S'il est pair, je veux le ramener à l'impair
immédiatement inférieur. Je vois deux façons d'écrire ça :
-> if(i % 2 == 0) i--; // foin des accolades, c'est un exemple !
-> i -= 1 - (i % 2);
Je me demandais laquelle des solutions est la plus rapide à
l'exécution ?
Ca va dependre du compilo et du processeur cible. Avec un processeur
n'ayant d'execution conditionnelle que pour les sauts, il y a des
chances pour que la deuxieme soit plus rapide. Des choix de ce genre
peuvent aussi dependre du contexte et de comment le compilo arrive a
associer les operations avec ce qui les entourent.
Cela dépend-il du compilateur ?
Et des parametres d'optimisation aussi.
Déclarer i en int ou en long a-t-il un effet là-dessus ?
Ca depend principalement du processeur cible. Tu peux aussi avoir des
differences avec unsigned.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Soit une variable i entière et initialisée. Je veux que i soit impair. S'il est pair, je veux le ramener à l'impair immédiatement inférieur. Je vois deux façons d'écrire ça : -> if(i % 2 == 0) i--; // foin des accolades, c'est un exemple ! -> i -= 1 - (i % 2);
Je me demandais laquelle des solutions est la plus rapide à l'exécution ?
Ca va dependre du compilo et du processeur cible. Avec un processeur n'ayant d'execution conditionnelle que pour les sauts, il y a des chances pour que la deuxieme soit plus rapide. Des choix de ce genre peuvent aussi dependre du contexte et de comment le compilo arrive a associer les operations avec ce qui les entourent.
Cela dépend-il du compilateur ?
Et des parametres d'optimisation aussi.
Déclarer i en int ou en long a-t-il un effet là-dessus ?
Ca depend principalement du processeur cible. Tu peux aussi avoir des differences avec unsigned.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Pierre Maurette
"Philippe Guglielmetti" a écrit:
"Jean-Noël Mégoz" a écrit
Soit une variable i entière et initialisée. Je veux que i soit impair. S'il est pair, je veux le ramener à l'impair
immédiatement inférieur. Je vois deux façons d'écrire ça : -> if(i % 2 == 0) i--; // foin des accolades, c'est un exemple !
-> i -= 1 - (i % 2); Je me demandais laquelle des solutions est la plus rapide à l'exécution ?
la seconde, et très nettement car il n'y a pas de test et donc pas de rupture dans le flux d'instructions et donc le pipeline du proc reste bien plein. La première forme doit pouvoir s'écrire:
i -= (i % 2 == 0); Pas de test EN C, mais je ne suis pas convaincu que le code généré soit DE CE FAIT optimal.
On peut d'ailleurs encore faire encore mieux: i-= 1-(i&1); qui ne fait pas de division. Là, en revanche, un compilateur (en restant en x86) traitant (i % 2)
par une division m'inquièterai sérieusement.
Le problème est dans le fait que l'impair doit être inférieur au pair. Il n'y a pas de soluition triviale en assembleur. En nous contentant d'instructions classiques que l'on doit trouver sur la plupart des processeurs (microcontrôleurs ?), et donc en oubliant les "test et agit" de Intel pas nécessairement performantes, si nous ne voulons ni division ni test/branche, on peut penser à:
dec dword ptr i ; Décrémenter i de 1. or dword ptr i, 1 ; Allumer le LSB de i.
Comment "suggérer" ça en C++ ?
--i |= 1;
(sur un compilateur testé, ça fonctionne et génère bien les deux lignes d'asm)
nota: doit fonctionner à peu près sur des plateformes courantes. Résultat non conforme pour les négatifs si codage signe + valeur absolue.
Cela dépend-il du compilateur ? non, je ne crois pas qu'il y ait des compilos assez malins pour
"convertir" le source de la première méthode en exécutable sans test et sans division. Je pense que si. Je vérifierai à l'occasion, n particulier avec VC++
7.1.
Philippe - www.goulu.net
"Philippe Guglielmetti" <newz@goulu.net> a écrit:
"Jean-Noël Mégoz" a écrit
Soit une variable i entière et initialisée.
Je veux que i soit impair. S'il est pair, je veux le ramener à
l'impair
immédiatement inférieur. Je vois deux façons d'écrire ça :
-> if(i % 2 == 0) i--; // foin des accolades, c'est un
exemple !
-> i -= 1 - (i % 2);
Je me demandais laquelle des solutions est la plus rapide à
l'exécution ?
la seconde, et très nettement car il n'y a pas de test et donc pas de
rupture dans le flux d'instructions et donc le pipeline du proc reste
bien plein.
La première forme doit pouvoir s'écrire:
i -= (i % 2 == 0);
Pas de test EN C, mais je ne suis pas convaincu que le code généré
soit DE CE FAIT optimal.
On peut d'ailleurs encore faire encore mieux: i-= 1-(i&1); qui ne
fait pas de division.
Là, en revanche, un compilateur (en restant en x86) traitant (i % 2)
par une division m'inquièterai sérieusement.
Le problème est dans le fait que l'impair doit être inférieur au pair.
Il n'y a pas de soluition triviale en assembleur. En nous contentant
d'instructions classiques que l'on doit trouver sur la plupart des
processeurs (microcontrôleurs ?), et donc en oubliant les "test et
agit" de Intel pas nécessairement performantes, si nous ne voulons ni
division ni test/branche, on peut penser à:
dec dword ptr i ; Décrémenter i de 1.
or dword ptr i, 1 ; Allumer le LSB de i.
Comment "suggérer" ça en C++ ?
--i |= 1;
(sur un compilateur testé, ça fonctionne et génère bien les deux
lignes d'asm)
nota: doit fonctionner à peu près sur des plateformes courantes.
Résultat non conforme pour les négatifs si codage signe + valeur
absolue.
Cela dépend-il du compilateur ?
non, je ne crois pas qu'il y ait des compilos assez malins pour
"convertir" le source de la première méthode en exécutable sans test
et sans division.
Je pense que si. Je vérifierai à l'occasion, n particulier avec VC++
Soit une variable i entière et initialisée. Je veux que i soit impair. S'il est pair, je veux le ramener à l'impair
immédiatement inférieur. Je vois deux façons d'écrire ça : -> if(i % 2 == 0) i--; // foin des accolades, c'est un exemple !
-> i -= 1 - (i % 2); Je me demandais laquelle des solutions est la plus rapide à l'exécution ?
la seconde, et très nettement car il n'y a pas de test et donc pas de rupture dans le flux d'instructions et donc le pipeline du proc reste bien plein. La première forme doit pouvoir s'écrire:
i -= (i % 2 == 0); Pas de test EN C, mais je ne suis pas convaincu que le code généré soit DE CE FAIT optimal.
On peut d'ailleurs encore faire encore mieux: i-= 1-(i&1); qui ne fait pas de division. Là, en revanche, un compilateur (en restant en x86) traitant (i % 2)
par une division m'inquièterai sérieusement.
Le problème est dans le fait que l'impair doit être inférieur au pair. Il n'y a pas de soluition triviale en assembleur. En nous contentant d'instructions classiques que l'on doit trouver sur la plupart des processeurs (microcontrôleurs ?), et donc en oubliant les "test et agit" de Intel pas nécessairement performantes, si nous ne voulons ni division ni test/branche, on peut penser à:
dec dword ptr i ; Décrémenter i de 1. or dword ptr i, 1 ; Allumer le LSB de i.
Comment "suggérer" ça en C++ ?
--i |= 1;
(sur un compilateur testé, ça fonctionne et génère bien les deux lignes d'asm)
nota: doit fonctionner à peu près sur des plateformes courantes. Résultat non conforme pour les négatifs si codage signe + valeur absolue.
Cela dépend-il du compilateur ? non, je ne crois pas qu'il y ait des compilos assez malins pour
"convertir" le source de la première méthode en exécutable sans test et sans division. Je pense que si. Je vérifierai à l'occasion, n particulier avec VC++
7.1.
Philippe - www.goulu.net
K. Ahausse
"Philippe Guglielmetti" a écrit dans le message de news:414a75d3$0$21019$
"Jean-Noël Mégoz" a écrit
Soit une variable i entière et initialisée. Je veux que i soit impair. S'il est pair, je veux le ramener à l'impair
immédiatement inférieur. Je vois deux façons d'écrire ça : -> if(i % 2 == 0) i--; // foin des accolades, c'est un exemple !
-> i -= 1 - (i % 2);
i -= (~i & 1) , ça marche et en plus l'optimisation est simplissime.
Exemple sur 80x86 :
mov eax, i // charger variable i dans accu mov ecx, eax // copie de i dans le registre ecx not ecx and ecx,1 sub eax, ecx mov i, eax // sauver accu dans variable i
"Philippe Guglielmetti" <newz@goulu.net> a écrit dans le message de
news:414a75d3$0$21019$5402220f@news.sunrise.ch...
"Jean-Noël Mégoz" a écrit
Soit une variable i entière et initialisée.
Je veux que i soit impair. S'il est pair, je veux le ramener à
l'impair
immédiatement inférieur. Je vois deux façons d'écrire ça :
-> if(i % 2 == 0) i--; // foin des accolades, c'est un
exemple !
-> i -= 1 - (i % 2);
i -= (~i & 1) , ça marche et en plus l'optimisation est simplissime.
Exemple sur 80x86 :
mov eax, i // charger variable i dans accu
mov ecx, eax // copie de i dans le registre ecx
not ecx
and ecx,1
sub eax, ecx
mov i, eax // sauver accu dans variable i
"Philippe Guglielmetti" a écrit dans le message de news:414a75d3$0$21019$
"Jean-Noël Mégoz" a écrit
Soit une variable i entière et initialisée. Je veux que i soit impair. S'il est pair, je veux le ramener à l'impair
immédiatement inférieur. Je vois deux façons d'écrire ça : -> if(i % 2 == 0) i--; // foin des accolades, c'est un exemple !
-> i -= 1 - (i % 2);
i -= (~i & 1) , ça marche et en plus l'optimisation est simplissime.
Exemple sur 80x86 :
mov eax, i // charger variable i dans accu mov ecx, eax // copie de i dans le registre ecx not ecx and ecx,1 sub eax, ecx mov i, eax // sauver accu dans variable i
Fabien LE LEZ
On Fri, 17 Sep 2004 09:19:47 +0200, Alexandre Bacquart :
Moi personnellement, je pense qu'il faut toujours se méfier des manipulations de bits en C et C++.
Avec des entiers non signés, on peut parfois s'en sortir.
-- ;-)
On Fri, 17 Sep 2004 09:19:47 +0200, Alexandre Bacquart
<tek512@hotmail.com>:
Moi personnellement, je pense qu'il faut toujours se méfier des
manipulations de bits en C et C++.
Avec des entiers non signés, on peut parfois s'en sortir.
On Fri, 17 Sep 2004 09:19:47 +0200, Alexandre Bacquart :
Moi personnellement, je pense qu'il faut toujours se méfier des manipulations de bits en C et C++.
Avec des entiers non signés, on peut parfois s'en sortir.
-- ;-)
Pierre Maurette
Fabien LE LEZ a écrit:
On Fri, 17 Sep 2004 09:19:47 +0200, Alexandre Bacquart :
Moi personnellement, je pense qu'il faut toujours se méfier des manipulations de bits en C et C++.
Avec des entiers non signés, on peut parfois s'en sortir. Bonjour,
Le thème (plus C que C++ en fait) revient souvent. Il est clair que d'un coté les manipulations de bits et la portabilté absolue ne font pas bon ménage. Et que d'un autre coté les ignorer "à priori" fait perdre au C une partie de son essence. Il me semble également qu'il est souvent plus simple (le plus sûr), dans la mesure où la cible est connue, d'utiliser un bloc _asm{} que des manips de bits en C (C++). Je peux ainsi manipuler des signed sans comportement indéfini. (la différence est que l'assembleur x86 me permet un décalage arithmétique et un décalage logique tous deux parfaitment définis). Mais bon, c'est un peu un marronnier, tout ça ;-) -- Pierre
Fabien LE LEZ <gramster@gramster.com> a écrit:
On Fri, 17 Sep 2004 09:19:47 +0200, Alexandre Bacquart
<tek512@hotmail.com>:
Moi personnellement, je pense qu'il faut toujours se méfier des
manipulations de bits en C et C++.
Avec des entiers non signés, on peut parfois s'en sortir.
Bonjour,
Le thème (plus C que C++ en fait) revient souvent. Il est clair que
d'un coté les manipulations de bits et la portabilté absolue ne font
pas bon ménage. Et que d'un autre coté les ignorer "à priori" fait
perdre au C une partie de son essence.
Il me semble également qu'il est souvent plus simple (le plus sûr),
dans la mesure où la cible est connue, d'utiliser un bloc _asm{} que
des manips de bits en C (C++). Je peux ainsi manipuler des signed sans
comportement indéfini. (la différence est que l'assembleur x86 me
permet un décalage arithmétique et un décalage logique tous deux
parfaitment définis).
Mais bon, c'est un peu un marronnier, tout ça ;-)
--
Pierre
On Fri, 17 Sep 2004 09:19:47 +0200, Alexandre Bacquart :
Moi personnellement, je pense qu'il faut toujours se méfier des manipulations de bits en C et C++.
Avec des entiers non signés, on peut parfois s'en sortir. Bonjour,
Le thème (plus C que C++ en fait) revient souvent. Il est clair que d'un coté les manipulations de bits et la portabilté absolue ne font pas bon ménage. Et que d'un autre coté les ignorer "à priori" fait perdre au C une partie de son essence. Il me semble également qu'il est souvent plus simple (le plus sûr), dans la mesure où la cible est connue, d'utiliser un bloc _asm{} que des manips de bits en C (C++). Je peux ainsi manipuler des signed sans comportement indéfini. (la différence est que l'assembleur x86 me permet un décalage arithmétique et un décalage logique tous deux parfaitment définis). Mais bon, c'est un peu un marronnier, tout ça ;-) -- Pierre
Pierre Maurette
"K. Ahausse" a écrit:
"Philippe Guglielmetti" a écrit dans le message de news:414a75d3$0$21019$
"Jean-Noël Mégoz" a écrit
Soit une variable i entière et initialisée. Je veux que i soit impair. S'il est pair, je veux le ramener à l'impair
immédiatement inférieur. Je vois deux façons d'écrire ça : -> if(i % 2 == 0) i--; // foin des accolades, c'est un exemple !
-> i -= 1 - (i % 2);
i -= (~i & 1) , ça marche et en plus l'optimisation est simplissime.
Exemple sur 80x86 :
mov eax, i // charger variable i dans accu mov ecx, eax // copie de i dans le registre ecx not ecx and ecx,1 sub eax, ecx mov i, eax // sauver accu dans variable i
--i |= 1 , ça marche et en plus l'optimisation est hyper simplissime.
Exemple sur 80x86 : dec i // variable - 1 -> variable or 1, 1 // forçage du LSB de variable
-- Pierre
"K. Ahausse" <anonymous@discussions.microsoft.com> a écrit:
"Philippe Guglielmetti" <newz@goulu.net> a écrit dans le message de
news:414a75d3$0$21019$5402220f@news.sunrise.ch...
"Jean-Noël Mégoz" a écrit
Soit une variable i entière et initialisée.
Je veux que i soit impair. S'il est pair, je veux le ramener à
l'impair
immédiatement inférieur. Je vois deux façons d'écrire ça :
-> if(i % 2 == 0) i--; // foin des accolades, c'est un
exemple !
-> i -= 1 - (i % 2);
i -= (~i & 1) , ça marche et en plus l'optimisation est simplissime.
Exemple sur 80x86 :
mov eax, i // charger variable i dans accu
mov ecx, eax // copie de i dans le registre ecx
not ecx
and ecx,1
sub eax, ecx
mov i, eax // sauver accu dans variable i
--i |= 1 , ça marche et en plus l'optimisation est hyper simplissime.
Exemple sur 80x86 :
dec i // variable - 1 -> variable
or 1, 1 // forçage du LSB de variable
"Philippe Guglielmetti" a écrit dans le message de news:414a75d3$0$21019$
"Jean-Noël Mégoz" a écrit
Soit une variable i entière et initialisée. Je veux que i soit impair. S'il est pair, je veux le ramener à l'impair
immédiatement inférieur. Je vois deux façons d'écrire ça : -> if(i % 2 == 0) i--; // foin des accolades, c'est un exemple !
-> i -= 1 - (i % 2);
i -= (~i & 1) , ça marche et en plus l'optimisation est simplissime.
Exemple sur 80x86 :
mov eax, i // charger variable i dans accu mov ecx, eax // copie de i dans le registre ecx not ecx and ecx,1 sub eax, ecx mov i, eax // sauver accu dans variable i
--i |= 1 , ça marche et en plus l'optimisation est hyper simplissime.
Exemple sur 80x86 : dec i // variable - 1 -> variable or 1, 1 // forçage du LSB de variable