Un petit problem en conversion de binaire en hexadécimal
Fermé
Sasan202
Messages postés
15
Date d'inscription
vendredi 23 novembre 2012
Statut
Membre
Dernière intervention
15 février 2013
-
15 févr. 2013 à 00:08
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 - 16 févr. 2013 à 11:37
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 - 16 févr. 2013 à 11:37
A voir également:
- Un petit problem en conversion de binaire en hexadécimal
- Éditeur hexadécimal en ligne - Télécharger - Édition & Programmation
- Codage binaire - Guide
- Petit 3 ✓ - Forum Word
- Comment imprimer une photo en petit ✓ - Forum Photo numérique
- Ème en petit ✓ - Forum LibreOffice / OpenOffice
2 réponses
mamiemando
Messages postés
33446
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
20 décembre 2024
7 812
15 févr. 2013 à 01:31
15 févr. 2013 à 01:31
Pourquoi ne pas simplement écrire ceci ?
Bonne chance
#include <stdio.h> int main() { unsigned n; printf("n = ?\n"); scanf("%d", &n); printf("n = %x\n", n); return 0; }
Bonne chance
mamiemando
Messages postés
33446
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
20 décembre 2024
7 812
Modifié par mamiemando le 16/02/2013 à 11:41
Modifié par mamiemando le 16/02/2013 à 11:41
Mercii Mais cé possible tu peut m'aider à résourde ça avec Méthode des calcul ;)
Merci de soigner l'orthographe.
Supposons que ce soit un entier encodé sur 4 octets. 1 octet = 2^8 = 256 valeurs possibles ce qui s'encode en hexadécimal de 00 à ff. Ainsi un entier 32 bits vaut en représentation hexadécimale entre 00 00 00 00 et ff ff ff ff avec la valeur de poids fort correspondant à 16^7 et la valeur de poids faible à 16^0.
Bon ok, maintenant il y a deux stratégies. Première école, l'approche indépendante de la base (ici 16) qui consiste à faire des divisions et des modulos. On utilise alors les opérateurs % et / Ça marche tout à fait mais c'est pas super performant car une division, ça coûte cher.
Autre école, on sait que la représentation d'un entier en mémoire est organisée en bits de poids forts et de poids faible et on regarde bit à bit la valeur en mémoire. On utilise alors les opérateurs & et <<. Le seul piège dans cette approche, c'est que si l'entier est signé, l'un des bits sert à stocker le signe. Normalement cette approche est indépendante de l'endianess du système (voir wikipedia big endian et little endian).
Voici ce que ça donne pour obtenir une écriture binaire :
Dans l'idée j'ai i qui va de 0 (inclu) à imax (exclu) avec imax = 32 - 1 = 31 pour exclure le bit de signe. Ensuite comme on écrit de droite à gauche il faut considérer les bits en partant du bit de poids fort vers ceux de poids faible, et ma variable j fait ce renversement. On aurait aussi pu écrire la boucle directement avec j mais il faut être assez prudent quand on manipule des boucles où l'on décrémente et pour lesquelles on s'arrête à 0 car il y a des pièges avec les entiers signés et non signés. Bref j'ai écrit la boucle dans ce sens car je préfère.
Ensuite les puristes aurait calculé imax avec imax = sizeof(int) << 3 - 1, car une multiplication par 8 revient à décaler les bits de trois crans vers la gauche, mais bon on va dire que ce n'est pas très important...
Ok maintenant il suffit de considérer les bits par pack de 4 au lieu de les considérer 1 par 1 pour avoir une représentation hexadécimale.
Ici je maintiens un pack de 4 bits dans un tableau, que j'affiche une fois que j'ai rempli les 4 cases correspondantes.
Ok dernière couche de polish, plutôt que de maintenir un tableau de 4 bits, je fais directement mémoriser la valeur entière associée à ces 4 bits (donc une valeur entre 0 et 15). Je n'aurai alors plus qu'à faire un switch en fonction de cette valeur pour afficher le bon caractère hexadécimal. Je vais noter cette valeur hex.
Alors encore une fois, on pourrait sommer les 4 puissances de 2 rencontrées mais on peut aussi travailler au niveau bit avec l'opérateur |=. Il faut juste penser à initialiser hex à 0 à avant de lire un pack de 4 bits.
... donne :
Virons le tableau bits, on n'en a plus besoin :
À ce stade on triche un peu car on exploite printf("%x") pour obtenir le caractère hexadécimal de la valeur hex, comprise entre 0 et 15. Alors encore une fois deux stratégies. Je peux faire un gros switch pour chacune des 16 valeurs, mais ça fait un code un peu fastidieux à écrire. Je peux aussi m'appuyer sur le fait que dans la représentation ascii, les caractères 0 à 9 et a à f sont deux plages de caractères consécutives.
https://fr.wikipedia.org/wiki/American_Standard_Code_for_Information_Interchange#Table_des_128_caract.C3.A8res_ASCII
Ainsi :
- si hex est dans {0, ... 9} : le caractère ascii correspondant est le hex-ième caractère après '0' dans la table ascii
- si hex est dans {10, ... 15} : le caractère ascii correspondant est le (hex - 10)-ième caractère après 'a' dans la table ascii
La caractère c ascii correspondant à hex est donc :
D'où le code :
Bonne chance
Merci de soigner l'orthographe.
Supposons que ce soit un entier encodé sur 4 octets. 1 octet = 2^8 = 256 valeurs possibles ce qui s'encode en hexadécimal de 00 à ff. Ainsi un entier 32 bits vaut en représentation hexadécimale entre 00 00 00 00 et ff ff ff ff avec la valeur de poids fort correspondant à 16^7 et la valeur de poids faible à 16^0.
Bon ok, maintenant il y a deux stratégies. Première école, l'approche indépendante de la base (ici 16) qui consiste à faire des divisions et des modulos. On utilise alors les opérateurs % et / Ça marche tout à fait mais c'est pas super performant car une division, ça coûte cher.
Autre école, on sait que la représentation d'un entier en mémoire est organisée en bits de poids forts et de poids faible et on regarde bit à bit la valeur en mémoire. On utilise alors les opérateurs & et <<. Le seul piège dans cette approche, c'est que si l'entier est signé, l'un des bits sert à stocker le signe. Normalement cette approche est indépendante de l'endianess du système (voir wikipedia big endian et little endian).
Voici ce que ça donne pour obtenir une écriture binaire :
#include <stdio.h> int main() { unsigned i, j, imax; int x = 69; imax = 8 * sizeof(int) - 1; for(i = 0; i < imax; ++i) { j = imax - 1 - i; printf("%d", (x & 1 << j) ? 1 : 0); } printf("\n"); return 0; }
Dans l'idée j'ai i qui va de 0 (inclu) à imax (exclu) avec imax = 32 - 1 = 31 pour exclure le bit de signe. Ensuite comme on écrit de droite à gauche il faut considérer les bits en partant du bit de poids fort vers ceux de poids faible, et ma variable j fait ce renversement. On aurait aussi pu écrire la boucle directement avec j mais il faut être assez prudent quand on manipule des boucles où l'on décrémente et pour lesquelles on s'arrête à 0 car il y a des pièges avec les entiers signés et non signés. Bref j'ai écrit la boucle dans ce sens car je préfère.
Ensuite les puristes aurait calculé imax avec imax = sizeof(int) << 3 - 1, car une multiplication par 8 revient à décaler les bits de trois crans vers la gauche, mais bon on va dire que ce n'est pas très important...
Ok maintenant il suffit de considérer les bits par pack de 4 au lieu de les considérer 1 par 1 pour avoir une représentation hexadécimale.
#include <stdio.h> int main() { unsigned i, j, imax, idx; int x = 69; short bits[4] = {0, 0, 0, 0}; imax = 8 * sizeof(int) - 1; for(i = 0; i < imax; ++i) { j = imax - 1 - i; idx = j % 4; bits[idx] = (x & 1 << j) ? 1 : 0; if (j % 4 == 0) { printf("%d%d%d%d ", bits[3], bits[2], bits[1], bits[0]); } } printf("\n"); return 0; }
Ici je maintiens un pack de 4 bits dans un tableau, que j'affiche une fois que j'ai rempli les 4 cases correspondantes.
Ok dernière couche de polish, plutôt que de maintenir un tableau de 4 bits, je fais directement mémoriser la valeur entière associée à ces 4 bits (donc une valeur entre 0 et 15). Je n'aurai alors plus qu'à faire un switch en fonction de cette valeur pour afficher le bon caractère hexadécimal. Je vais noter cette valeur hex.
Alors encore une fois, on pourrait sommer les 4 puissances de 2 rencontrées mais on peut aussi travailler au niveau bit avec l'opérateur |=. Il faut juste penser à initialiser hex à 0 à avant de lire un pack de 4 bits.
#include <stdio.h> int main() { unsigned i, j, imax, idx; int x = 69; short bits[4] = {0, 0, 0, 0}; short hex = 0; imax = 8 * sizeof(int) - 1; for(i = 0; i < imax; ++i) { j = imax - 1 - i; idx = j % 4; bits[idx] = (x & 1 << j) ? 1 : 0; hex |= bits[idx] << idx; if (j % 4 == 0) { printf("%d%d%d%d (%x) ", bits[3], bits[2], bits[1], bits[0], hex); hex = 0; } } printf("\n"); return 0; }
... donne :
(mando@silk) (~) $ gcc plop.c && ./a.out 0000 (0) 0000 (0) 0000 (0) 0000 (0) 0000 (0) 0000 (0) 0100 (4) 0101 (5)
Virons le tableau bits, on n'en a plus besoin :
#include <stdio.h> int main() { unsigned i, j, imax; int x = 69; short hex = 0; imax = 8 * sizeof(int) - 1; for(i = 0; i < imax; ++i) { j = imax - 1 - i; hex |= ((x & 1 << j) ? 1 : 0) << (j % 4); if (j % 4 == 0) { printf("%x", hex); hex = 0; } } printf("\n"); return 0; }
À ce stade on triche un peu car on exploite printf("%x") pour obtenir le caractère hexadécimal de la valeur hex, comprise entre 0 et 15. Alors encore une fois deux stratégies. Je peux faire un gros switch pour chacune des 16 valeurs, mais ça fait un code un peu fastidieux à écrire. Je peux aussi m'appuyer sur le fait que dans la représentation ascii, les caractères 0 à 9 et a à f sont deux plages de caractères consécutives.
https://fr.wikipedia.org/wiki/American_Standard_Code_for_Information_Interchange#Table_des_128_caract.C3.A8res_ASCII
Ainsi :
- si hex est dans {0, ... 9} : le caractère ascii correspondant est le hex-ième caractère après '0' dans la table ascii
- si hex est dans {10, ... 15} : le caractère ascii correspondant est le (hex - 10)-ième caractère après 'a' dans la table ascii
La caractère c ascii correspondant à hex est donc :
c = hex < 10 ? '0' + hex : 'a' + hex - 10;
D'où le code :
#include <stdio.h> int main() { unsigned i, j, imax; int x = 69; short hex = 0; imax = (sizeof(int) << 3) - 1; for(i = 0; i < imax; ++i) { j = imax - 1 - i; hex |= ((x & 1 << j) ? 1 : 0) << (j % 4); if (j % 4 == 0) { printf("%c", hex < 10 ? '0' + hex : 'a' + hex - 10); hex = 0; } } printf("\n"); return 0; }
Bonne chance
15 févr. 2013 à 01:44
Mais Svp tu peut m'expliquer ce que tu vient ecrire ?
ça fonctionne Correctement mais sera mieux si tu m'explique ça
Merciii à nouveau :)
15 févr. 2013 à 02:21
Tu verras que le format %x permet d'écrire un nombre entier sous forme hexadécimale.
Bonne chance
15 févr. 2013 à 22:02