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 Float vers char[4]


Sujet :

C++

  1. #1
    Membre très actif Avatar de Argol_Medusa
    Homme Profil pro
    Ingénieur Radiofréquences
    Inscrit en
    Août 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Radiofréquences
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 208
    Par défaut Conversion Float vers char[4]
    Bonjour,

    j'ai des nombres en long int ( sur 4 octets ) que je souhaite ajouter dans une trame de char.
    pour ce faire, j'utilise le procédé suivant :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    char RX_Value[30];
    long int valeur=123456;
    RX_Value[0] = valeur       & 0xFF;
    RX_Value[1] = (valeur>>8)  & 0xFF;
    RX_Value[2] = (valeur>>16) & 0xFF;
    RX_Value[3] = (valeur>>24) & 0xFF;
    jusque là tout va bien

    Maintenant j'aimerai fais la meme chose pour un nombre codé en float ( 4 octets ).

    j'ai essaye le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    long int *tmp;
    float valeur_float;
    valeur_float = 123456.2;
    tmp=&valeur_float;
    afin d'avoir dans tmp les 4 octets qui me permettraient de stocker ensuite dans le tableau de char :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    RX_Value[0] = *tmp  & 0xFF;
    RX_Value[1] = (*tmp>>8)  & 0xFF;
    RX_Value[2] = (*tmp>>16) & 0xFF;
    RX_Value[3] = (*tmp>>24) & 0xFF;
    Mais le compilater ( visual studio ) refuse de compiler en mettant le message d'erreur suivant :

    c:\projet\ttcpip.cpp(367) : error C2440: '=' : cannot convert from 'float *' to 'long *'

    Quelqu'un sait-il comment réussir à copier ce float sur un char de 4 octet ( sans qu'il n'y ait de conversion ) ?

    Merci d'avance

  2. #2
    Membre éprouvé
    Inscrit en
    Avril 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 155
    Par défaut
    hello,

    tente ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        long int *tmp;
        float valeur_float;
        valeur_float = 123456.2;
        tmp= (long int *)&valeur_float;

  3. #3
    Membre éprouvé
    Inscrit en
    Avril 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 155
    Par défaut
    en fait ce que tu veux récupérer c'est quoi?
    ==>
    Les nombres de type float sont codés sur 32 bits dont :
    * 23 bits pour la mantisse
    * 8 bits pour l'exposant
    * 1 bit pour le signe

    ou bien la valeur?

  4. #4
    Membre éclairé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 190
    Par défaut
    Salut à tous !

    Citation Envoyé par loicounet Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        long int *tmp;
        float valeur_float;
        valeur_float = 123456.2;
        tmp= (long int *)&valeur_float;
    Quel horreur ! Une conversion de type C, la chose qu'il vaut mieux éviter en C++... static_cast, const_cast et dynamic_cast et reinterpret_cast sont la pour ça.

    Cela dit, pour répondre à Argol_Medusa, j'aurais besoin de savoir si tu veux convertir le flottant en entier long, où si tu veux enregistrer sa représentation binaire dans un entier long, ce qui n'est pas la même chose. Dans le premier cas, il s'agit d'une conversion, dans l'autre non.

    À bientôt.

    Le Farfadet Spatial

  5. #5
    Membre très actif Avatar de Argol_Medusa
    Homme Profil pro
    Ingénieur Radiofréquences
    Inscrit en
    Août 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Radiofréquences
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 208
    Par défaut
    Bonjour et merci pour vos réponses,

    Oui en fait je ne veux pas convertir un float en long int ( je perdrais l'information sur les décimales), mais prendre les 4 octets du float
    ( les 23 bits pour la mantisse, 8 bits pour l'exposant, 1 bit pour le signe ) et les mettre dans un tableau de Char : RX_Value[]

    Ce RX_Value[] contient des octets d'une trame, que je dois modifier, en remplaçant 4 octets (les premiers dans l'exemple que j'ai pris au-dessus) par un float avant réémission.


    Trame RX_Value[30] _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
    float ( 4 octets )______________/


    Je connaissais pas les static_cast, const_cast et dynamic_cast, je vais regarder l'aide sur ces fonctions c'est peut-etre la solution

  6. #6
    Membre éclairé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 190
    Par défaut
    Salut à tous !

    Citation Envoyé par Argol_Medusa Voir le message
    Je connaissais pas les static_cast, const_cast et dynamic_cast, je vais regarder l'aide sur ces fonctions c'est peut-etre la solution
    Non, ce n'est pas la solution : ces opérateurs sont là pour effectuer des conversions.

    C'est quelque chose de très spécifique que tu cherches à faire, vu que tu veux conserver exactement la même représentation binaire, mais en considérant les variables qui stockent les données non plus comme flottantes, mais comme entiers longs. Il y a un sujet sur Developpez.com qui parle de choses qui ressemblent un peu à ce que tu veux faire, je vais essayer de le retrouver.

    À bientôt.

    Le Farfadet Spatial

  7. #7
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    float mon_float = (float)12.34;
    unsigned long int *ptr = (unsigned long int *)&mon_float;
    unsigned long value = *ptr;
    TRACE(L"float %f=%ld", mon_float, value);
    Resultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    float 12.340000=1095069860
    Je pense que cela marche mais quelle horreur !!
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  8. #8
    Membre éclairé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 190
    Par défaut
    Salut à tous !

    Je n'ai pas testé la solution de Ram_0000, peut-être a-t-elle l'effet escompté.

    À bientôt.

    Le Farfadet Spatial

  9. #9
    Membre très actif Avatar de Argol_Medusa
    Homme Profil pro
    Ingénieur Radiofréquences
    Inscrit en
    Août 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Radiofréquences
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 208
    Par défaut
    Citation Envoyé par ram_0000 Voir le message

    Resultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    float 12.340000=1095069860
    Je pense que cela marche mais quelle horreur !!


    Oui c'est exactement ça, ça marche !! Merci beaucoup !

    Du coup j'ai trouvé aussi une autre méthode avec ( mea culpa ) un memcpy :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    	unsigned char RX_Value[30];
        float valeur_float = 12.34;
        long int entier;
        memcpy( &entier, &valeur_float, 4 ); 
     
    	RX_Value[0] = entier       & 0xFF;
    	RX_Value[1] = (entier>>8)  & 0xFF;
    	RX_Value[2] = (entier>>16) & 0xFF;
    	RX_Value[3] = (entier>>24) & 0xFF;
    	printf("source = %lf et destination = %ld\n",valeur_float,entier);
    sortie :

    source = 12.340000 et destination = 1095069860

  10. #10
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    De manière générale, il ne faut JAMAIS faire la moindre prédiction sur la manière dont les différents types primitifs sont représentés en mémoire...

    En effet, tout ce que la norme indique, c'est:
    1. Que tout type est composé d'un nombre entier de char
    2. sizeof(char) = 1 = sizeof(unsigned char) = sizeof(signed char)
    3. char <= short <= int <= long <= (long long)
    4. unsigned char<= unsigned short <= unsigned int <= unsigned long <= (unsigned long long)
    5. signed char<= signed short <= signed int <= signed long <= (signed long long)

    Et comme on ne peut déjà même pas être sur du nombre de bits utilisé par un char (qui correspond simplement au nombre de bits nécessaires à la représentation de tous les caractères présents dans la table de caractères de référence), on se rend compte qu'il devient pour ainsi dire impossible de faire la moindre prédiction

    Dés lors, il est fortement conseillé, une fois de plus, de passer par les flux de conversion pour s'assurer que l'on récupère bien la donnée telle qu'elle devait se présenter

    De manière générale, cela prend une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int monentier = 15698;// il peut venir de n'importe où ;)
    std::stringstream ss;
    ss<<monentier;
    std::string chaine=ss.str();
    //on peut récupérer le nombre de caractères composant la chaine grace à
    ss.size();
    //ou à 
    ss.length();
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  11. #11
    Membre très actif Avatar de Argol_Medusa
    Homme Profil pro
    Ingénieur Radiofréquences
    Inscrit en
    Août 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Radiofréquences
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 208
    Par défaut
    Heu ... c'est à dire, si je suis le raisonnement, qu'un char n'est pas forcément codé sur 1 octet, ou plutot qu'un long int n'est pas forcément codé sur 4 octets c'est ça ?

    Est-ce que ça dépend uniquement de la machine cible sur laquelle on compile ( PC, microcontroleur ... ) ou est-ce que sur une même machine ( PC par exemple ) on peut avoir des tailles différentes suivant les compilateurs ?

  12. #12
    Membre éclairé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 190
    Par défaut
    Salut à tous !

    Citation Envoyé par Argol_Medusa Voir le message
    Est-ce que ça dépend uniquement de la machine cible sur laquelle on compile ( PC, microcontroleur ... ) ou est-ce que sur une même machine ( PC par exemple ) on peut avoir des tailles différentes suivant les compilateurs ?
    Comme la norme ne le précise pas, il peut y avoir des différences entre compilateurs.

    Dans les faits, les concepteurs de compilateurs implémentent les types en fonction du matériel, donc les différences sont surtout entre machines différentes.

    La norme C99 propose des types dont la taille est fixée par la norme. C++ 0x devrait, si je ne m'abuse, les introduire également.

    À bientôt.

    Le Farfadet Spatial

  13. #13
    Membre très actif Avatar de Argol_Medusa
    Homme Profil pro
    Ingénieur Radiofréquences
    Inscrit en
    Août 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Radiofréquences
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 208
    Par défaut
    D'accord, merci beaucoup pour toutes ces précisions.

  14. #14
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Tu n'a effectivement déjà aucune garantie qu'un "char" soit codé sur 8 bits.

    On a vu, si j'ai bonne mémoire, des cas où ils étaient codés sur 6 bits, et on pourrait très bien envisager qu'un compilateur décide qu'il n'y a pas de différence entre char et char_w, et qu'un char soit donc codé sur 16...

    De plus, en prenant le "char" comme unité (le plus petit type primitif représentable), on sait que tous les types seront composés de multiples parfaits du nombre de bits d'un char.

    Ainsi, il n'est pas question, avec un char composé de 8 bits, d'envisager un type qui soit composé 20 ou 12 bits

    Mais le nombre de char qui entre dans chaque type n'est absolument pas fixé (et je n'ai pas l'impression que C++ 0x ait décidé de changer cela )

    Ainsi, je sais que chez moi, un short fait 2 char (ce qui correspond bien à char <= short), mais il pourrait très bien en faire 3 chez toi, ton voisin ou ton meilleur ami...

    On sait enfin qu'un char, un signed char et un unsigned char seront composés du même nombre de bits, mais on n'a aucune garantie q'un short, un unsigned short et un signed seront composés du même nombre de char.

    Et ce qui est vrai ici pour un short est valable pour tous les autres types primitifs.

    En outre, on n'a aucune certitude que ce soit l'unsigned int qui serve pour les pointeur et pour les "size type" (size_t), bien que la norme considère qu'il s'agisse d'un candidat idéal pour ce faire.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  15. #15
    Membre éclairé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 190
    Par défaut
    Salut à tous !

    Citation Envoyé par koala01 Voir le message
    Mais le nombre de char qui entre dans chaque type n'est absolument pas fixé (et je n'ai pas l'impression que C++ 0x ait décidé de changer cela )
    Moi non plus, je n'ai rien vu qui aille dans le sens de changer cet état de faits.

    À bientôt.

    Le Farfadet Spatial

  16. #16
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Citation Envoyé par Le Farfadet Spatial Voir le message
    Salut à tous !



    Moi non plus, je n'ai rien vu qui aille dans le sens de changer cet état de faits.

    À bientôt.

    Le Farfadet Spatial
    Et pourtant, c'est bien toi qui a écrit
    Citation Envoyé par Le Farfadet Spatial Voir le message
    <snip>
    La norme C99 propose des types dont la taille est fixée par la norme. C++ 0x devrait, si je ne m'abuse, les introduire également.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  17. #17
    Membre éclairé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 190
    Par défaut
    Salut à tous !

    Attention, j'ai dit qu'il me semble que C++ 0x va intégrer les types dont la taille est fixée. D'abord, je conçois aisément que je peux faire une erreur.

    Cela dit, je n'ai jamais dit que j'avais vu que la taille des char, par exemple, allait être fixée, ni que le nombre de char dans un int sera déterminée : ce n'est pas parce qu'on peut utiliser int16_t ou uint32_t qu'on peut en déduire qu'un long contient 4 char.

    À bientôt.

    Le Farfadet Spatial

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

Discussions similaires

  1. Conversion wchar_t ** vers char**
    Par progfou dans le forum C++
    Réponses: 21
    Dernier message: 23/02/2007, 10h12
  2. conversion gchar vers char
    Par shito dans le forum GTK+ avec C & C++
    Réponses: 1
    Dernier message: 16/01/2007, 20h09
  3. Problème conversion float vers double
    Par jhenaff dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 27/01/2006, 10h39
  4. [MFC] Problème de conversion CString vers Char *
    Par Darkenshin dans le forum MFC
    Réponses: 10
    Dernier message: 02/12/2005, 14h42
  5. Conversion float vers int
    Par vargasvan dans le forum C
    Réponses: 2
    Dernier message: 05/10/2005, 17h29

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