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
[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
A voir également:
- Insérer un string dans un tableau de type hexa
- Tableau croisé dynamique - Guide
- Insérer une vidéo dans powerpoint - Guide
- Comment faire un tableau - Guide
- Code ascii tableau - Guide
- Insérer signature word - Guide
8 réponses
Utilisateur anonyme
7 juin 2013 à 09:06
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?
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?
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.
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.
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
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
Utilisateur anonyme
7 juin 2013 à 13:41
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 :
de cette manière, tu reconstitue des partie de ta valeur.
pour ton cas:
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;
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!!
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!!
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)
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)
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
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
[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
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
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
[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
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
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
[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
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 :
Cela va copier, à partir de msg[4], les octets suivants, dans cet ordre sur une machine little-endian :
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).
#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).
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
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?
je veux 0x3f, 0x8c, 0xcc, 0xcd, sinon il n y a pas d'autre solution valable quelque soit le type du processeur?
[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
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.
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
#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
Utilisateur anonyme
10 juin 2013 à 07:47
10 juin 2013 à 07:47
je réponds au premier post de dal : (je ne veux pas pourrir votre fil ^^)
Tu dis :
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
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
[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
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
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