BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019
-
16 juil. 2003 à 15:43
yann_lo_san
Messages postés1137Date d'inscriptionlundi 17 novembre 2003StatutMembreDernière intervention23 janvier 2016
-
2 août 2006 à 22:41
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
yann_lo_san
Messages postés1137Date d'inscriptionlundi 17 novembre 2003StatutMembreDernière intervention23 janvier 201626 2 août 2006 à 22:41
Pourquoi ne pas rajouter la version avec complément à deux ? Pour avoir les représenations des négatifs aussi.
Pour bypasser la récursion faire
static bool neg = false;
static int param = n;
si param < 0
si neg = false;
neg = true
inverser tous les bits de param avec not (~)
rajouter 1 à ce résultat (complément à 2)
fin si
ton code avec param
fin si
else
code normal avec n positif
fin
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 17 juil. 2003 à 17:23
JCDjcd, tu sais bien que je ne me prends pas pour la SERNAM.
cs_JCDjcd
Messages postés1138Date d'inscriptionmardi 10 juin 2003StatutMembreDernière intervention25 janvier 20094 17 juil. 2003 à 17:13
Heu ... bof bof :
sizeof(int)*CHAR_BIT pour etre le plus protable possible !
JackosKing
Messages postés168Date d'inscriptionmardi 31 décembre 2002StatutMembreDernière intervention21 avril 2005 17 juil. 2003 à 16:09
oups... :p
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 17 juil. 2003 à 15:44
sizeof(int)*8
cs_NiFF
Messages postés92Date d'inscriptiondimanche 2 juin 2002StatutMembreDernière intervention24 juin 2004 17 juil. 2003 à 15:42
Non sizeof ne donne pas le nombre de bits
JackosKing
Messages postés168Date d'inscriptionmardi 31 décembre 2002StatutMembreDernière intervention21 avril 2005 17 juil. 2003 à 14:07
déjà en indentant, ca fait plus qu'une ligne:p
void Dec2Bin(int n)
{
if(0!=n)
Dec2Bin(n/2);
printf("%1d",n & 1);
}
bon sinon je propose:
DecToBin(int x)
{
int i = sizeof(int);
while(i--) // optimise en dbf (enfin faut espérer..)
putchar( (char)(x>>i)&1 + '0' );
}
cs_NiFF
Messages postés92Date d'inscriptiondimanche 2 juin 2002StatutMembreDernière intervention24 juin 2004 17 juil. 2003 à 00:22
Hé ben ça m'étonne mais il faut bien reconnaitre que c'est récursif.
Je le commente rapidos:
_n$ = 8
?Dec2Bin@@YAXH@Z PROC NEAR ;début de procédure
push esi ; on sauve esi
mov esi, DWORD PTR _n$[esp] ;esi prend la valeur n
test esi, esi; si esi=0 alors
je SHORT $L55536; on va à fin:
mov eax, esi; eax=esi
cdq; convertit le mot signé EAX en un quadruple mot dans EDX:EAX
sub eax, edx ; eax= eax-edx . Pourquoi faire?
sar eax, 1; division par deux de eax
push eax; mis en paramètre sur la pile
call ?Dec2Bin@@YAXH@Z ; appel récursif
and esi, 1; esi=0+1=1
push esi; esi sur la pile pour affichage
push OFFSET FLAT:??_C@_03GNGPFOOL@?$CF1d?$AA@
call _printf; affichage
add esp, 12; aucune idée ???
fin:
pop esi; on libère la pile
ret 0; retour 0
?Dec2Bin@@YAXH@Z ENDP; fin
bien joué quand même, et c'est bizarre qu'il distingue deux cas. Il faudrait essayer en optimisant en vitesse ou en taille. Je crois même me souvenir que VS 2003 a une option de dérécursification. À vérifier...
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 16 juil. 2003 à 22:48
Le compilo a genere ce qui est ecrit comme code et pas autre chose.
En enlevant le sprintf, ok il avait enleve la recursion mais avec le sprintf nenni !
Compilo = VS 2003
_n$ = 8
?Dec2Bin@@YAXH@Z PROC NEAR
push esi
mov esi, DWORD PTR _n$[esp]
test esi, esi
je SHORT $L55536
mov eax, esi
cdq
sub eax, edx
sar eax, 1
push eax
call ?Dec2Bin@@YAXH@Z
and esi, 1
push esi
push OFFSET FLAT:??_C@_03GNGPFOOL@?$CF1d?$AA@
call _printf
add esp, 12
$L55536:
pop esi
ret 0
?Dec2Bin@@YAXH@Z ENDP
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 16 juil. 2003 à 22:25
ben pour vous mettre d'accord recompile et demande la sortie asm au compilo. Tu nous fais un copier coller ici du bloc asm de la fonction et on jugera sur pieces.
cs_NiFF
Messages postés92Date d'inscriptiondimanche 2 juin 2002StatutMembreDernière intervention24 juin 2004 16 juil. 2003 à 21:59
JCDjcd>>Le compilateur n'est pas cense etre Intelligent... il ne faut pas compter dessus !
Un compilateur ne peut pas générer du code récursif, et il sait reconnaitre une fonction récursive et la dérécursifier, notamment à l'aide de piles.
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 16 juil. 2003 à 19:10
oui JackosKing mais la tu peux y compter, le compilo en bon automate stupide ne le ratera pas.
JackosKing
Messages postés168Date d'inscriptionmardi 31 décembre 2002StatutMembreDernière intervention21 avril 2005 16 juil. 2003 à 19:00
de meme n/2 sera optimisé en n>>1, mais bon...
cs_JCDjcd
Messages postés1138Date d'inscriptionmardi 10 juin 2003StatutMembreDernière intervention25 janvier 20094 16 juil. 2003 à 18:37
Le compilateur n'est pas cense etre Intelligent... il ne faut pas compter dessus !
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 16 juil. 2003 à 16:27
C'est l'empilage de param qui est long compare a de l'iteratif ou il n'y en a pas.
Ma remarque etait destinee surtout aux debutants, il vaut toujours mieux leur preciser les avantages et inconvenients.
cs_NiFF
Messages postés92Date d'inscriptiondimanche 2 juin 2002StatutMembreDernière intervention24 juin 2004 16 juil. 2003 à 16:10
Chacun optimise son code comme il le souhaite, et u développeur peut avoir de très bonnes raisons d'économiser de la place. Ce code est court au niveau C, mais il est possible qu'il soit plus long compilé. Pour ce qui est de la vitesse, les appels récursifs sont souvent dérécursifiés par le compilateur, et les décalages de bits (division) et les masques sont assez rapides.
Le but de ce code n'est pas de proposer quelque chose de plus court à écrire, mais d'expliquer la technique qui peut être utilisée ici.
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 16 juil. 2003 à 15:43
Le but d'un prog n'etant pas que le developpeur ait le moins de lignes a ecrire, je ne conseillerais donc pas l'emploi de ta methode qui s'avere beaucoup plus lente qu'un decalage de bit iteratif.
2 août 2006 à 22:41
Pour bypasser la récursion faire
static bool neg = false;
static int param = n;
si param < 0
si neg = false;
neg = true
inverser tous les bits de param avec not (~)
rajouter 1 à ce résultat (complément à 2)
fin si
ton code avec param
fin si
else
code normal avec n positif
fin
17 juil. 2003 à 17:23
17 juil. 2003 à 17:13
sizeof(int)*CHAR_BIT pour etre le plus protable possible !
17 juil. 2003 à 16:09
17 juil. 2003 à 15:44
17 juil. 2003 à 15:42
17 juil. 2003 à 14:07
void Dec2Bin(int n)
{
if(0!=n)
Dec2Bin(n/2);
printf("%1d",n & 1);
}
bon sinon je propose:
DecToBin(int x)
{
int i = sizeof(int);
while(i--) // optimise en dbf (enfin faut espérer..)
putchar( (char)(x>>i)&1 + '0' );
}
17 juil. 2003 à 00:22
Je le commente rapidos:
_n$ = 8
?Dec2Bin@@YAXH@Z PROC NEAR ;début de procédure
push esi ; on sauve esi
mov esi, DWORD PTR _n$[esp] ;esi prend la valeur n
test esi, esi; si esi=0 alors
je SHORT $L55536; on va à fin:
mov eax, esi; eax=esi
cdq; convertit le mot signé EAX en un quadruple mot dans EDX:EAX
sub eax, edx ; eax= eax-edx . Pourquoi faire?
sar eax, 1; division par deux de eax
push eax; mis en paramètre sur la pile
call ?Dec2Bin@@YAXH@Z ; appel récursif
and esi, 1; esi=0+1=1
push esi; esi sur la pile pour affichage
push OFFSET FLAT:??_C@_03GNGPFOOL@?$CF1d?$AA@
call _printf; affichage
add esp, 12; aucune idée ???
fin:
pop esi; on libère la pile
ret 0; retour 0
?Dec2Bin@@YAXH@Z ENDP; fin
bien joué quand même, et c'est bizarre qu'il distingue deux cas. Il faudrait essayer en optimisant en vitesse ou en taille. Je crois même me souvenir que VS 2003 a une option de dérécursification. À vérifier...
16 juil. 2003 à 22:48
En enlevant le sprintf, ok il avait enleve la recursion mais avec le sprintf nenni !
Compilo = VS 2003
_n$ = 8
?Dec2Bin@@YAXH@Z PROC NEAR
push esi
mov esi, DWORD PTR _n$[esp]
test esi, esi
je SHORT $L55536
mov eax, esi
cdq
sub eax, edx
sar eax, 1
push eax
call ?Dec2Bin@@YAXH@Z
and esi, 1
push esi
push OFFSET FLAT:??_C@_03GNGPFOOL@?$CF1d?$AA@
call _printf
add esp, 12
$L55536:
pop esi
ret 0
?Dec2Bin@@YAXH@Z ENDP
16 juil. 2003 à 22:25
16 juil. 2003 à 21:59
Un compilateur ne peut pas générer du code récursif, et il sait reconnaitre une fonction récursive et la dérécursifier, notamment à l'aide de piles.
16 juil. 2003 à 19:10
16 juil. 2003 à 19:00
16 juil. 2003 à 18:37
16 juil. 2003 à 16:27
Ma remarque etait destinee surtout aux debutants, il vaut toujours mieux leur preciser les avantages et inconvenients.
16 juil. 2003 à 16:10
Le but de ce code n'est pas de proposer quelque chose de plus court à écrire, mais d'expliquer la technique qui peut être utilisée ici.
16 juil. 2003 à 15:43