IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Conversion hexa vers double


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Par défaut Conversion hexa vers double
    Bonjour,

    Je dispose d'une chaine de caractére qui represente en hexadecimal une valeur double (64bits) et je voudrais récuperer cette valeur double dans une variable.

    je me demandais donc s'il fallait que je passe par la structure en mémoire d'un DOUBLE càd 1bit de signe 11 pour l'exposant et 52 pour la mantisse et me faire tout à la main ou s'il y avait une astuce.

    Merci d'avance.

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Si tu es certain que c'est le bon format binaire pour le double (y compris pour l'endianness), une bête copie/transformation en mémoire ferait l'affaire.
    Commence par te faire une fonction du genre:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    void HexToMem(void *dest, char const *hexDigits, size_t nBytes);
    Et ensuite, l'appeler ainsi:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    double maValeur;
    char const * doubleEnHexa = "F0E1D2C3B4A59687";
    HexToMem(&maValeur, doubleEnHexa, sizeof(maValeur));
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre chevronné Avatar de straasha
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juillet 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2004
    Messages : 149
    Par défaut
    trouve en cherchant "atof" sous un celebre moteur de recherche

    Nom
    atof - Conversion d'une chaîne en réel (double).
    Synopsis


    #include <stdlib.h>
    double atof (const char *nptr);
    Description
    La fonction atof() convertit le début de la chaîne pointée par nptr en un réel de type double. Le résultat est identique à un appel

    strtod(nptr, (char **)NULL);
    à la différence que atof() ne détecte pas d'erreur.

    Valeur Renvoyée
    Le résultat de la conversion.
    Conformité
    SVID 3, POSIX, BSD 4.3, ISO 9899
    Voir Aussi
    atoi(3) , atol(3) , strtod(3) , strtol(3) , strtoul(3)

    [edit]
    oups j'ai du lire trop vite et zapper le "hexadecimal"
    desole
    [\edit]

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    straasha : atof() et strtod() ne convertissent qu'un nombre flottant exprimé en décimal.

    Ici, à moins que le P.O. se soit mal exprimé, la chaîne contient la représentation en hexa des octets bruts du double.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Par défaut
    Bein je vais donner un exemple :

    je parse un fichier binaire dont je traite les infos en hexadécimale.

    Pour valeur double telque -6,625 je récupere 0000 0000 0080 1AC0 que j'inverse pour avoir les poids forts a gauche et j'ai donc C01A 8000 0000 0000 qui correspond bien à ma valeur mais je n'arrive pas à convertir simplement cela.

    Sachant que dans le même cas avec des entier 32 bits j'ai fais simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    // ou optmp est ma chaine contenant l'hexa
    sscanf(optmp,"%08x",&val);
    sprintf(value,"%d",val);
    mais cela n'est pas possible aussi facilement avec un double.

    @Medinoc : peut-tu m'expliquer le principe je comprend pas ce que tu appelle une bete transformation en memoire...

    P.S.: je vois PO souvent ca veut dire quoi ?

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    P.O. signifie Posteur Originel.

    Et par transformation, je voulais dire "transformer à-la-volée de l'hexa en octets bruts".
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par EnigmuS
    Je dispose d'une chaine de caractére qui represente en hexadecimal une valeur double (64bits) et je voudrais récuperer cette valeur double dans une variable.

    je me demandais donc s'il fallait que je passe par la structure en mémoire d'un DOUBLE càd 1bit de signe 11 pour l'exposant et 52 pour la mantisse et me faire tout à la main ou s'il y avait une astuce.
    Le format des doubles étant dépendants de l'implémentation, il n'y a pas d'autre solution que de reporter les bits 'à la main', ce qui peut être assez compliqué... Il faut pour cela connaitre le format des données en hexadécimal, et celui des doubles de l'implémentation. Ensuite, il faut faire coïncider, en sachant qu'il y a des risques de perte d'information.

    Je sens que Jean Marc va sortir du bois...

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Naturellement, il est possible que le format que ta chaîne hexadécimale représente coïncide déjà avec le format de cette implémentation des double, auquel cas il te suffit d'écrire simplement sur le mémoire du double.
    Mais il faut être 100% certain que c'est le cas sur toutes les plate-formes que ton programme doit supporter.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 42
    Par défaut
    Ok merci,

    pour en revenir à HexToMem sur le principe c'est bien de mettre mon nombre hexa bit à bit dans une structure de double en esperant que ca correspondent ? Si oui je comprend bien le principe mais pas l'implémentation ici pour un entier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void hextomem(int *mem, const char *hexa, int taille)
    {
        int i;
        for(i = 0; i < len; i++) 
        {
            mem[i] = ((hexa[0]) << 4) |(hexa[1]);
            buf += 2;
        }
    }

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Voici une implémentation plus ou moins portable qui convertit la chaîne octet par octet en utilisant strtoul() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    int HexToMem(void *dest, char const *hexDigits, size_t nBytes)
    {
    	size_t iByte;
    	size_t iChar = 0;
    	unsigned char * const destBytes = dest;
    	char buf[3] = {0, 0, 0};
     
    	/* Convertit octet par octet. */
    	for(iByte=0 ; iByte<nBytes ; iByte++)
    	{
    		char c = hexDigits[iChar++];
    		if(c=='\0')
    			return -1; /* Chaîne trop courte */
    		buf[0] = c;
     
    		c = hexDigits[iChar++];
    		if(c=='\0')
    			return -1; /* Chaîne trop courte */
     
    		buf[1] = c;
    		destBytes[iByte] = (unsigned char)strtoul(buf, NULL, 16);
    	}
    	return 0; /* OK */
    }
    On peut faire plus performant en convertissant soi-même les caractères hexadécimaux en leur valeur, mais on perdrait sûrement la portabilité pour d'autres charsets que l'ASCII...

    J'en ai aussi profité pour rajouter une valeur de retour, qui indique si la chaîne était trop courte pour remplir toute la destination...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Médinoc
    Voici une implémentation portable
    (Attention a la presomption, ca ne fonctionne pas sur mon PDP-10 favori avec ses bytes a 9 bits... )

    J'en ai aussi profité pour rajouter une valeur de retour, qui indique si la chaîne était trop courte pour remplir toute la destination...
    Tu aurais pu aussi ajouter la verification que la valeur donnee etait bien un nombre hexa.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 27/01/2009, 10h30
  2. Conversion hexa vers float (selon norme IEEE754)
    Par vinssieux dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 29/05/2008, 11h58
  3. Conversion single ou double vers hexa
    Par vinssieux dans le forum VB.NET
    Réponses: 4
    Dernier message: 29/04/2008, 10h20
  4. Problème conversion float vers double
    Par jhenaff dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 27/01/2006, 10h39
  5. [langage] conversion décimal vers hexa
    Par chipster dans le forum Langage
    Réponses: 2
    Dernier message: 23/02/2004, 16h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo