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 :

codage des floats sur 4 bytes


Sujet :

C

  1. #1
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 947
    Points : 1 351
    Points
    1 351
    Par défaut codage des floats sur 4 bytes
    Salut,

    je suis sur un protocole de transmission série où tout est en bigendian. Pour envoyer un 32 bits je fais donc quelquechose du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    send_ubyte((my_u32 & 0xff000000) >> 24);
    send_ubyte((my_u32 & 0x00ff0000) >> 16);
    send_ubyte((my_u32 & 0x0000ff00) >> 8);
    send_ubyte((my_u32 & 0x000000ff));
    Quelquesoit l'endianess de my_u32, les bytes sont toujours placé de la même façon dans la trame. Comme ce protocle va servir à connecter des PC et des cartes à différents petits micros (8051, PIC etc...) et différents compilos, comment puis-je assurer la même indépendance au niveau des float32 (sans passer par des #define)?

    A+

    Pfeuh

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Plusieurs choix :

    + faire du binaire et envoyer les float comme les entier.

    Pour cela, il suffit de transtyper [EDIT]l'adresse (merci diogène) d'un float en entier [/EDIT] : on ne convertit pas la valeur, mais on stocke les bits du float dans un entier pour utiliser les opérateur binaires et de décalage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /* il faut un type entier de la même taille que le flottant */
    /* ASSERT(sizeof(float) == sizeof(int)); */
    void send_float(float f) {
        int fake_float;
        fake_float = *(int*)(&f); /*EDIT: merci Melem */
        /* envoyer fake_float*/
        send_ubyte((fake_float & 0xff000000) >> 24);
        send_ubyte((fake_float & 0x00ff0000) >> 16);
        send_ubyte((fake_float & 0x0000ff00) >> 8);
        send_ubyte((fake_float & 0x000000ff));
    }
    Le problème de cette méthode est qu'on finira toujours par trouver une plateforme sur laquelle cette astuce ne fonctionne pas.
    [edit]
    Cette astuce fonctionne si
    • on a un type entier de la même taille que le type flottant
    • la représentation des flottant est la même sur les eux architectures (IEEE745)

    [/edit]
    + faire du mode texte :
    Mais le problème est qu'il faut revoir le protocole.

    + ne pas utiliser des flottant, mais des fixés : cela revient à utiliser des entier, tout en sachant où placer une virgule après réception.
    Dernière modification par Invité(e) ; 27/01/2010 à 14h56. Motif: Prise en compte des remarques de Melem

  3. #3
    Membre éclairé
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Points : 842
    Points
    842
    Par défaut
    C'est dangereux d'envoyer des nombres flottants tels quels ! Si l'hôte de destination n'a pas la même représentation des nombres flottants que la machine source, tu auras des problèmes. Le mieux est encore de convertir ton float en chaîne de caractères, de l'envoyer, et celui qui reçoit la convertit en nombre flottant. De cette manière tu ne devrais pas avoir de problèmes (du moins tu seras sûr que ton nombre arrive entier à l'autre bout).

    Si tu tiens à les envoyer tels quels, tu peux tout simplement utiliser un 'union'
    Plus tu pédales moins fort, moins t'avances plus vite.

  4. #4
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Si tu tiens à les envoyer tels quels, tu peux tout simplement utiliser un 'union'
    Sûrement pas. Le *(int*)(&f) (mabu aussi voulait sûrement écrire &f) est largement à préférer aux unions. Les unions en C ANSI servent à économiser de la mémoire, pas à faire des réinterprétations de bits. Sinon, utiliser un pointeur de unsigned char qu'on fait pointeur sur le premier octet du float me semble la meilleure solution.

  5. #5
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    @mabu :
    Pour cela, il suffit de transtyper (je ne suis pas sur du mot) un float en entier : on ne convertit pas la valeur, mais on stocke les bits du float dans un entier
    Libellé dangereux, puisque le transtypage d'un float en int change la représentation binaire.
    Ce n'est heureusement pas ce que fait ton code qui lui transtype bien l'adresse du float en une adresse d'entier.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  6. #6
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 947
    Points : 1 351
    Points
    1 351
    Par défaut
    Citation Envoyé par mabu Voir le message
    faire du binaire et envoyer les float comme les entier.
    Merci, ça me semble être la meilleure solution si un float32 est placé en mémoire comme un entier 32.

    Citation Envoyé par Pouet_forever Voir le message
    C'est dangereux d'envoyer des nombres flottants tels quels ! Si l'hôte de destination n'a pas la même représentation des nombres flottants que la machine source, tu auras des problèmes.
    le format des flottants en petit embarqué est toujours float32 IEEE 754, comme le type float sur PC.

    Citation Envoyé par Pouet_forever Voir le message
    Le mieux est encore de convertir ton float en chaîne de caractères, de l'envoyer, et celui qui reçoit la convertit en nombre flottant.
    On cherche à avoir les temps de transmission les plus courts, les plus prévisibles et les plus répétables, donc cette solution n'est pas envisageable.

    Merci à tous.

    Pfeuh

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

Discussions similaires

  1. convertir floats sur 4 bytes (IEEE754)
    Par morgan_2956 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 01/03/2010, 17h17
  2. Ecrire des float dans un stream en tant que byte[]
    Par Baud10 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 30/11/2008, 18h45
  3. IE6 ajoute des espaces sur div float
    Par deejay2221 dans le forum Mise en page CSS
    Réponses: 8
    Dernier message: 15/08/2008, 11h25
  4. Comment avoir des div sur une même ligne sans utiliser float ?
    Par Sergejack dans le forum Balisage (X)HTML et validation W3C
    Réponses: 10
    Dernier message: 13/10/2007, 15h31
  5. Test if sur des float
    Par Minuit dans le forum Linux
    Réponses: 2
    Dernier message: 26/03/2005, 13h08

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