begin process at 2012 05 27 15:25:46
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Astuces

 > DEC-BINAIRE: 1 LIGNE!

DEC-BINAIRE: 1 LIGNE!


 Information sur la source

Note :
1 / 10 - par 2 personnes
1,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Astuces Niveau :Débutant Date de création :16/07/2003 Date de mise à jour :16/07/2003 15:38:09 Vu :4 598

Auteur : NiFF

Ecrire un message privé
Commentaire sur cette source (17)
Ajouter un commentaire et/ou une note

 Description

Afficher l'équivalent binaire d'un nombre en une ligne.

Voici sans doute la source la plus simple (la plus rapide?) pour convertir un nombre décimal en binaire.
Considérons par exemple le nombre décimal 43.
Il s'écrit "0 0 1 0 1 0 1 1" en binaire (sur 8 bits)

43/2 = 21 (en entier).
21 s'écrit "0 0 0 1 0 1 0 1" sur le même nombre de bits.

Vous pouvez remarquer que tous les bits ont été décalés vers la droite, c'est le principe de la divison par 2.
0 0 1 0 1 0 1 1 = 43
0 0 0 1 0 1 0 1 = 43/2 = 21
0 0 0 0 1 0 1 0 = 43/2/2 = 21/2 = 10

etc.

Il suffit donc de diviser par deux jusqu'à ce qu'on arrive au nombre 0 pour que tous les bits passent à la position de droite. Mais nous voulons que le bit de gauche soit affiché en 1°. Il faudra donc d'abord tout diviser avant de commencer à afficher.

Nous devons également utiliser un masque. Le masque 1, qui s'écrit "0 0 0 0 0 0 0 1" en binaire sur 8 bits, nous servira à extraire le bit de droite d'un nombre.

on fait une opération "et" sur chaque bit. Cette opération renvoie 1 si les deux chiffres sont à 1.

  0 0 1 0 1 0 1 1
& 0 0 0 0 0 0 0 1
  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
  0 0 0 0 0 0 0 1

On aura donc en résultat du masque le bit de droite, tous les autres étant mis à zéro.

Notre algorithme sera donc:

Procédure binaire (n: entier) {
si n est différent de 0 alors rappeler binaire (n / 2) et afficher (n & 1) }

le décalage des bits se fait lors de l'appel récursif, l'affichage lors du retour.
n différent de 0 est la condition de sortie, pour éviter une boucle infinie.

Effets de bord : si vous faites binaire(0), n'affiche rien.
Pour afficher un 0 devant tous les chiffres, il faut sortir l'affichage de la condition "if".

Avec un nombre négatif : Binaire(-n) a le même effet que binaire (n).

J'espère que vous avez compris.


Source

  • void Dec2Bin(int n){
  • if(0!=n) {Dec2Bin(n/2); printf("%1d",n & 1); }
  • }
  • //pour toujours mettre un zéro avant :
  • void Dec2Bin(int n){
  • if(0!=n) {Dec2Bin(n/2);} printf("%1d",n & 1);
  • }
  • // sur une ligne :
  • void Dec2Bin(int n){if(0!=n) {Dec2Bin(n/2);} printf("%1d",n & 1); }
void Dec2Bin(int n){

if(0!=n) {Dec2Bin(n/2); printf("%1d",n & 1); }

}

//pour toujours mettre un zéro avant : 

void Dec2Bin(int n){

if(0!=n) {Dec2Bin(n/2);} printf("%1d",n & 1); 

}

// sur une ligne :

void Dec2Bin(int n){if(0!=n) {Dec2Bin(n/2);} printf("%1d",n & 1); }

 Conclusion

des commentaires?


 Sources du même auteur

LE SWAP LE PLUS CRADE DE L'HISTOIRE DU C++

 Sources de la même categorie

Source avec Zip SCHEDULER RR FIFO par yvesB87
Source avec Zip ALGORITHMES RÉCURSIFS VS ALGORITHMES ITÉRATIFS par yvesB87
Source avec Zip Source avec une capture C++ FORMAT D'IMAGE AVEC QT par pop70
Source avec une capture EXEMPLE DE POINTEURS DE FONCTION par pop70
Source avec Zip Source avec une capture [C++] CLASS REGISTER par Miwik

Commentaires et avis

Commentaire de BruNews le 16/07/2003 15:43:54 administrateur CS

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.

Commentaire de NiFF le 16/07/2003 16:10:04

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.

Commentaire de BruNews le 16/07/2003 16:27:24 administrateur CS

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.

Commentaire de JCDjcd le 16/07/2003 18:37:36

Le compilateur n'est pas cense etre Intelligent... il ne faut pas compter dessus !

Commentaire de JackosKing le 16/07/2003 19:00:12

de meme n/2 sera optimisé en n>>1, mais bon...

Commentaire de BruNews le 16/07/2003 19:10:31 administrateur CS

oui JackosKing mais la tu peux y compter, le compilo en bon automate stupide ne le ratera pas.

Commentaire de NiFF le 16/07/2003 21:59:45

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.

Commentaire de BruNews le 16/07/2003 22:25:09 administrateur CS

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.

Commentaire de BruNews le 16/07/2003 22:48:40 administrateur CS

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

Commentaire de NiFF le 17/07/2003 00:22:34

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...

Commentaire de JackosKing le 17/07/2003 14:07:50

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' );
}  



Commentaire de NiFF le 17/07/2003 15:42:23

Non sizeof ne donne pas le nombre de bits

Commentaire de BruNews le 17/07/2003 15:44:18 administrateur CS

sizeof(int)*8

Commentaire de JackosKing le 17/07/2003 16:09:09

oups... :p

Commentaire de JCDjcd le 17/07/2003 17:13:14

Heu ... bof bof :
sizeof(int)*CHAR_BIT pour etre le plus protable possible !

Commentaire de BruNews le 17/07/2003 17:23:40 administrateur CS

JCDjcd, tu sais bien que je ne me prends pas pour la SERNAM.

Commentaire de yann_lo_san le 02/08/2006 22:41:49

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
      

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,484 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales