Insérer un string dans un tableau de type hexa

Fermé
yassine003 Messages postés 2 Date d'inscription jeudi 6 juin 2013 Statut Membre Dernière intervention 8 juin 2013 - Modifié par yassine003 le 6/06/2013 à 20:14
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 - 10 juin 2013 à 11:27
Bonjour,
je veux convertir une variable float en hexa puis insérer le résultat dans un tableau type hexa, il faut mettre cette variable float dans les 4 dernier champs du tableau:

char Tab_Hex[] = {0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00};//tableau des hexa
float Var_fl = 1.1; //variable float
sprintf(Var_fl,"%x",Var_fl); //conversion flot->hexa (1.1 -> 3f8ccccd)
//je veux mettre 3f dans Tab_Hex[4],8c dans Tab_Hex[5],cc dans Tab_Hex[6] et cd dans //Tab_Hex[7])
//ma proposition pour insérer 3f dans Tab_Hex[4] :
char temp[8];
temp[0] = Var_fl[0];
temp[1]= Var_fl[1];

Tab_Hex[4]= temp; // ca ne fonctionne pas !

Si vous pourriez m'aider s'il vous plait.
Merci.
A voir également:

8 réponses

Utilisateur anonyme
7 juin 2013 à 09:06
salut,

tu viens de convertir ton float en une valeur hexa, le seul moyen d'effectuer un découpage est de séparer les dizaines / milliers / etc, le même principe que pour une valeur entière en faite, mais je ne comprends pas trop pourquoi tu veux faire 3 valeurs d'une seule ... sauf peu être pour crypter?
0
merci pour votre réponse, oui en fait le but est de construire une trame.
donc je converti le float en char,
ma trame :
static char msg[6]={0x2F,0x76,0x63,0x73,0x00,0x00}

char packetString[10];
sprintf(packetString,"%x\n",*(unsigned int*)&f);
puis je dois concaténer deux caractère pour les insérer dans une case du tableau:
par exemple je fais,

1ere solution
string concatenation;
concatenation = packetString[0]+packetString[1];//ca marche pas

2eme solution
string concatenation;
concatenation[0] = packetString[0];
concatenation[1] = packetString[1];//ca marche pas

puis il faut insérer à chaque fois concatenation dans une case du tableau.
Merci de votre aide.
0
Salut, l'opérateur + pour la concaténation c'est que pour std::string il me semble (donc en c++), sinon il me semble que en C il y a string.h qui doit avoir la fonction strcat.
voir http://en.wikipedia.org/wiki/Schlemiel_the_Painter%27s_algorithm et http://www.techonthenet.com/c_language/standard_library_functions/string_h/strcat.php
0
Utilisateur anonyme
7 juin 2013 à 13:41
ok je vois. donc en fait le truc, c''est que tu pars du principe que ta valeur hexa est une chaine, ce qui est faut. Pour déterminer la chaine de caractère qui compose ta valeur c'est différent.

Pour prendre un exemple simple :
tu prends le caractère 'A', tu le converti en hexa, tu obtients 0x41. 0x41 est une valeur, ce n'est pas "0x41" (j'espère que tu me suis ^^). par contre, en binaire, ca fait : 0100 0001.
Si je fais ce code :
char A = 'A'; 
char tab[2];
tab[0] = A & 0x0F; //on récupère 0001
tab[1] = (A>>4) & 0x0F;//on récupère 0100


de cette manière, tu reconstitue des partie de ta valeur.
pour ton cas:

Tab_Hex[4]  = (Var_fl >>12 )&0xFF;//FF car tu veux les paires, 12 car tu veux la première paire sur 4
Tab_Hex[5]  = (Var_fl >>8)&0xFF;
Tab_Hex[6]  = (Var_fl >>4 )&0xFF;
Tab_Hex[7]  = Var_fl &0xFF;
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
merci pour l'explication,
en fait j'ai fait votre code mais le problème est que la variable issue de ma conversion n'est pas de type char:

f = 1.1f; //à convertir en hexa

char packetString[10];

sprintf(packetString,"%x\n",*(unsigned int*)&f);//convertir et stocker dans packetString

msg[4] = packetString & 0x0F; //non accepté par le compilateur!!
0
oui mais ca ne change rien, à partir du moment où tu détermine une valeur héxa et une seule, c'est pareil, tout comme 1 et 8547852 sont deux nombres.
ici on sait que la taille d'un float est 4 octets (8*4 bits donc) et toi tu convertit 8 bit par 8 bit. (si tu regarde l'exemple en rapport avec toi, je fais le traitement sur 8 bit)
0
Utilisateur anonyme
7 juin 2013 à 15:30
Pour info :
1 octet = 8 bit
c'est à dire une valeur comprise entre 0 et 255 (ou -127 et 128).
un float = 8*8 bits soit 64
donc beaucoup plus de valeur possible (je les ai pas en tete). Le but de l exercice est donc de découper par paquet de 8 bits pour générer des caractère, ici 4 (1 par octet).
Au final on aura donc une chaine de 4 caractères représentant un float
0
et pourquoi je n'arrive pas à compiler le code?
0
Utilisateur anonyme
7 juin 2013 à 15:53
là comme ca je pourrais pas te dire, tu as quoi comme message? quel est ton code?
0
float f=0.1;
char packetString[10];
sprintf(packetString,"%x\n",*(unsigned int*)&f);
msg[0] = packetString & 0x0F; //ca compile pas
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié par [Dal] le 7/06/2013 à 17:30
Salut yassine003,

Pourquoi veux-tu convertir un float en une représentation hexadécimale ?

je trouve un peu choquant de dire que 1.1 (un virgule un) égale 0x3f8ccccd (alors que 0x3f8ccccd est un entier valant 1066192077 dans le système décimal)...

Que cherches-tu à obtenir, la représentation interne en mémoire de l'ordinateur d'un float ayant la valeur de 1.1 sur ta machine ?

Nagashima a raison en indiquant que tu mélanges les valeurs des octets et leur représentation sous forme de caractères ASCII en faisant ton sprintf.

Mais, utiliser les opérateurs bit à bit sur autre chose qu'une valeur entière, je ne crois pas que cela soit possible (en tout cas, mon gcc n'en veut pas).


Dal
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié par [Dal] le 7/06/2013 à 17:52
Ton problème ressemble à un problème de sérialisation.

Tu pourrais t'inspirer des solutions mentionnées dans ce fil SO : https://stackoverflow.com/questions/1786137/c-serialization-of-the-floating-point-numbers-floats-doubles

Il y a des bibliothèques qui font cela, tu pourrais regarder leur code. Une bibliothèque (C++) est suggérée par un des contributeurs au fil.

Une des choses à prendre en compte est la endianness, c'est à dire l'ordre dans lequel les octets sont organisés en mémoire, qui n'est pas nécessairement celui que tu penses.

Les processeurs x86 sont basés sur une structure de type "mot de poids faible en tête" (architectures "little-endian") : https://fr.wikipedia.org/wiki/Endianness#Little_endian et l'ordre des octets est renversé par rapport à la lecture "normale".


Dal
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié par [Dal] le 7/06/2013 à 18:52
Si tu veux te contenter de copier la représentation en mémoire sur ta machine, tu devrais faire comme cela :

#include <stdio.h>
#include <string.h>

int main(void)
{
    static char msg[] =
    { 0x2F, 0x76, 0x63, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

    float f = 1.1;
    memmove(msg + 4, &f, sizeof(f));

    return 0;
}

Cela va copier, à partir de msg[4], les octets suivants, dans cet ordre sur une machine little-endian :

0xcd, 0xcc, 0x8c, 0x3f

Dal

Edit : cela est valable sur ma machine avec un processeur 32 bits sous Windows et un code compilé sous gcc ("float" n'est pas spécifié dans le standard du C, on sait juste que c'est de la "single precision" par rapport à "double"). Mais en pratique, sur la plupart des machines cela devrait être effectivement 4 octets actuellement (adhésion à un format proposé par l'IEEE : IEEE 754 single precision floating point).
0
yassine003 Messages postés 2 Date d'inscription jeudi 6 juin 2013 Statut Membre Dernière intervention 8 juin 2013
8 juin 2013 à 11:27
merci pour l'explication, c'est exactement ce que je veux, sauf que pour avoir 0xcd, 0xcc, 0x8c, 0x3f
je veux 0x3f, 0x8c, 0xcc, 0xcd, sinon il n y a pas d'autre solution valable quelque soit le type du processeur?
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
8 juin 2013 à 23:03
Pour les avoir dans l'ordre big-endian sur une machine little-endian, tu copies les octets un par un en partant de la fin.

#include <stdio.h>
#include <string.h>

int main(void)
{
    static char msg[] =
    { 0x2F, 0x76, 0x63, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

    float f = 1.1;
    void * f_ptr = &f;
    f_ptr = f_ptr + sizeof(f) - 1;
    char i;
    for (i = 0; i < sizeof(f); i++)
    {
        memmove(msg + 4 + i, f_ptr - i, 1);
    }

     return 0;
}

Cependant, comme indiqué plus haut, ton problème est un problème de "sérialisation" de tes données. Ces données que tu mets dans le tableau, tu vas en faire quelque chose : les stocker, les transmettre, etc. Le récepteur des données doit être capable de "désérialiser", c'est à dire de partir de ton format de représentation de données et de s'en servir pour récupérer la donnée stockée ou transmise.

Il faut qu'aux deux bouts il y ait une même convention sur le format des données sérialisées, et que chacun des bouts s'occupe des particularités liées à sa machine (endianness, notamment).


Dal
0
Utilisateur anonyme
10 juin 2013 à 07:47
je réponds au premier post de dal : (je ne veux pas pourrir votre fil ^^)

Tu dis :
je trouve un peu choquant de dire que 1.1 (un virgule un) égale 0x3f8ccccd (alors que 0x3f8ccccd est un entier valant 1066192077 dans le système décimal)


et justement tu vois que tu as une valeur entiere qui vient de la conversion de ton float => le bit à bit reste une bonne option. (il faudra juste ensuite ne pas oublier qu'il s'agit d'un float sinon il va récupérer des valeurs absurdes).

Ensuite il y avait 4 cases de prévues pour stocker le résultat de sa conversion => je penche pour un exercice, vu que le float est sur 4 octets mais que le posteur n'en avait pas l'air de le savoir.

Enfin bon, au final je pense que j'ai donné les info qui lui permettront de faire ce qu'il veut avec le bit à bit, à lui de voir s'il choisit ma solution ;)

bne journée
naga
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
10 juin 2013 à 11:27
Salut Nagashima :-)

OK, vu comme cela, c'est effectivement possible. Je pense que tu veux dire qu'il faut donc appliquer les opérations bit à bit sur l'entier présent en mémoire à l'endroit où est stocké le float. C'est à dire, en passant par une variable pointeur intermédiaire de type entier castée sur l'adresse du float.

Je pense aussi qu'il faudrait rectifier les décalages, car je ne pense pas que ceux que tu proposes tombent juste.

J'aime bien ta solution, elle donne un code C s'occupant de l'endianness.


Dal
0
Salut,

Dal : Votre solution fonctionne parfaitement je vous remercie infiniment.

nagashima: je vous remercie de m'avoir éclairci les idées concernant le calcul binaire ..
0