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
J'essaye de créer un programme en C pour convertir les nombres de décimal à Hexadécimal
le calcul est correct
le problem que j'ai On hexadécimal On a
10 = A
11 = B
12 = C
13 = D
14 = E
15 = F
et je veux mettre Ces caractére à la place de ces nombres
C'est mon Code en C :


#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
main()
{
int n,m,k,i,T[64] ;
i=0;
k=0;
printf("\n\tEntrez un nombre en decimal pour le convertir en hexadecimal: \t\t");
scanf("%d",&n);
m= n ;
do{
T[i]=n%16;
n=n/16;
i++;
k++;}
while(n!=0);
printf("\n\n\t\tla conversion de %d en hexadecimal est:\t\t",m);
for(i=k-1;i>=0;i--){
printf("%d",T[i]);}
getch();
}


Mercii d'avance :)
A voir également:

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
Pourquoi ne pas simplement écrire ceci ?

#include <stdio.h>

int main() {
    unsigned n;
    printf("n = ?\n");
    scanf("%d", &n);
    printf("n = %x\n", n);
    return 0;
} 


Bonne chance
0
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 à 01:44
Mercii pour ta réponse :)
Mais Svp tu peut m'expliquer ce que tu vient ecrire ?
ça fonctionne Correctement mais sera mieux si tu m'explique ça
Merciii à nouveau :)
0
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 à 02:21
Dans un terminal linux ou avec google :

man printf


Tu verras que le format %x permet d'écrire un nombre entier sous forme hexadécimale.

Bonne chance
0
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 à 22:02
Mercii Mais cé possible tu peut m'aider à résourde ça avec Méthode des calcul ;)
0
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
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 :

#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
0