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 :

Comment faire une fonction htonf (indianisme)?


Sujet :

C++

  1. #1
    Membre habitué Avatar de Jayceblaster
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    420
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 420
    Points : 174
    Points
    174
    Par défaut Comment faire une fonction htonf (indianisme)?
    Bonjour...

    Je souhaiterai ecrire une fonction qui recoit en entree un flotant et qui retourne un flotant apres avoir effectuer une conversion little big endian (host->network).
    Apres avoir cherchais j'ai rien trouvé quelqu'un peut il m'aider?

    Merci d'avance...
    Heureux est l'étudiant qui, comme la rivière, arrive à suivre son cours sans sortir de son lit........

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    float a;
     
    si architecture little endian alors
      char* b = reinterpret_cast<char*>(&a);
      std::swap(b[0], b[3]);
      std::swap[b[1], b[2]);
    sinon
      rien
    Bien entendu, ça reste pas portable dans l'absolu (que float soit du IEEE 754 n'est pas garanti, possibilité d'architecture middle endian)
    Boost ftw

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,

    Juste au passage, c'est Endianisme (ou plutot, en français, "boutisme"), car cela n'a rien à voir avec l'Inde
    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

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Franchement, je serais plutôt du genre à passer par le type entier correspondant, plutôt que char*.

    Cela permettrait d'utiliser htonl() pour les float, mais il n'y a malheureusement pas de htonll() qu'on pourrait utiliser pour les 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 Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    J'aimerai des précisions sur cette question.
    Le gros boutien, petit boutien c'est que pour les entiers ! Je ne comprends pas trop le problème... Un flotant n'est pas en gros ou petit boutien, c'est juste un flotant... Et donc sur un reseau, un flotant c'est un flotant... Il n'y a pas de transformation à faire...
    A l'origine, c'est car certaines machines travaillent avec des entiers en gros boutiens et des d'autres avec des entier en petit boutiens, et sur les réseaux on envoie du gros boutien, donc il fallait convertir pour les machine qui étaient en petit boutien natif....
    Première grosse démo en construction :
    http://bitbucket.org/rafy/exo2/

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Es-tu absolument sûr qu'il n'y a pas de boutisme pour un flottant? Je ne vois pas trop pourquoi il n'y en aurait pas...
    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 sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Il semblerait que les flottants suivent le boutisme
    Les flottants sont rarement évoqué. Ils sont en fait spécifié par la norme IEEE 754. Pour un flottant 32 bits, le 31ième bits est le bit de signe, ensuite vient l'exposant puis la mantisse. Encore faut-il savoir ou va le bit 31 de poids fort ou le bit 0 de poid faible dans la mémoire de la machine! En fait, il suive la même règle de "mélange des octets" que pour les entiers.
    (ma source)
    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

  8. #8
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    Bon j'ai fais des petites recherches sur l'endianness des flottants (eh ouais c'est comme ca qu'on dit apparement)
    Floating-point and endianness

    On some machines, while integers were represented in little-endian form, floating point numbers were represented in big-endian form. [3] Because there are many floating point formats, and a lack of a standard "network" representation, no standard for transferring floating point values has been made. This means that floating point data written on one machine may not be readable on another, and this is the case even if both use IEEE 754 floating point arithmetic since the endianness of the memory representation is not part of the IEEE specification. [4]
    J'ai trouvé ca ici : http://en.wikipedia.org/wiki/Endianness
    Désolé c'est en anglais.
    Je vais traduire un peu, pour les profanes et les feignasses (enfin je ne suis pas un traducteur né hein)
    Sur certaines machines, alors que les entiers sont représentés en petit boutien, les nombres flottants sont représentés en gros boutien. Comme il y a beaucoup de formats différents de représentation des flottants, et un manque de représentation standrad pour le réseau, aucune norme de transfert des nombres flottants n'a été établie. Cela veut dire que certains flottants écris sur une machine peuvent ne pas être lu par une autre, et même si elles utilisent toutes les deux l'arithmetique des flottants de l'IEEE 754 depuis que le bouttisme de la représentation mémoire ne fait plus partie des spécifications de l'IEEE
    La fin n'est pas top top bien traduite (s'il y a des traducteurs dans la salle), mais bon ce que je pense qu'on peut déduire de tout ca, c'est qu'en fait il n'y a pas de norme pour les flottants sur le réseau...
    On peut envoyer les flottants en gros boutien ou en petit boutien, tant que le gars qui recoit les données sait si c'est du gros ou du petit boutien et qu'il ne s'en mèle pas les pinceaux..... Ca va.
    Première grosse démo en construction :
    http://bitbucket.org/rafy/exo2/

  9. #9
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Franchement, je serais plutôt du genre à passer par le type entier correspondant, plutôt que char*.
    Passer par autre chose que char* briserait les règles d'aliasing strictes.
    De toutes façons passer par autre chose que char* n'a pas de sens pour inverser l'ordre des octets...
    Boost ftw

  10. #10
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    On some machines, while integers were represented in little-endian form, floating point numbers were represented in big-endian form. [3] Because there are many floating point formats, and a lack of a standard "network" representation, no standard for transferring floating point values has been made. This means that floating point data written on one machine may not be readable on another, and this is the case even if both use IEEE 754 floating point arithmetic since the endianness of the memory representation is not part of the IEEE specification. [4]
    Sur certaines machines, bien que les entiers soient représentés en petits boutiens, les flottants sont représentés en grands boutiens [3]. À cause du grand nombre de représentations des flottants, et de l'absence d'une représentation "réseau" répandue, aucun standard pour la transmission des flottants n'a été établi. Cela signifie que les flottants écrits sur une machine ne sont pas nécessairement lisibles sur une autre, même si les deux utilisent l'arithmétique de flottants IEEE754, car le boutisme ne fait pas partie de la spécification IEEE.[4]
    Attention au contresens sur le since .

  11. #11
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    Ouais je préfère ta version... Il y avait donc un interprète dans la salle
    Ca va j'avais quand même le sens, j'ai pas dis trop de bétises... toutoutou toutoutoudou !!
    (enfin j'avais dis que ma fin était foireuse)
    Merci à toi white_tentacle
    Bref, il y a du boutissme pour les flottants, mais aucune norme pour définir la manière de les envoyer sur un réseau.
    Donc pour répondre à notre ami qui a posté le message :
    Tu n'es peut-être pas obligé de transformer les flottants pour les envoyer sur le réseau. Tout d'abord, car il semblerai qu'ils soient déjà en gros boutien, donc taillé pour le réseau, mais en plus car, apparement, il n'y a aucune norme qui défini comment le faire.
    Bon après si tu veux quand même le faire je pense que une solution peut-être de passer par un entier :
    Après tout un float n'est rien d'autre que des bits, tu met ces bits dans un entier, tu switches et tu envoie, à la reception, tu déswitche et tu construit un float avec les bits ainsi obtenus...
    A grand coup de reinterpret_cast ca devrait fonctionner.
    Première grosse démo en construction :
    http://bitbucket.org/rafy/exo2/

  12. #12
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Rafy Voir le message
    Après tout un float n'est rien d'autre que des bits, tu met ces bits dans un entier, tu switches et tu envoie, à la reception, tu déswitche et tu construit un float avec les bits ainsi obtenus...
    A grand coup de reinterpret_cast ca devrait fonctionner.

    Personnellement, je passerais soit par une chaîne de caractère soit -si cela a un sens - par une représentation à virgule fixe : partie entière/partie décimale dans des entiers. Puis je reconstruis de l'autre côté. Tout simplement car tu n'as en théorie aucune idée de comment est représenté un float.
    Les autres solutions montrent au mieux que tu comprends la représentation IEEE 754 mais te créés du travail pour l'avenir : quand l'équipement en face n'aura pas cette représentation

    [EDIT] : tu dois mieux comprendre pourquoi htonf ne peut fiablement exister.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Passer par autre chose que char* briserait les règles d'aliasing strictes.
    De toutes façons passer par autre chose que char* n'a pas de sens pour inverser l'ordre des octets...
    J'ai du mal à comprendre ce que tu veux dire.

    Je pensais à un truc de ce genre:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    float htonf(float a)
    {
    	uint32_t const *pca = reinterpret_cast< uint32_t const * >(&a);
    	uint32_t const ret = htonl(*pca);
    	float const *pcret = reinterpret_cast< float const * >(&ret);
    	return *pcret;
    }
     
    //Ou sans variables intermédiaires pointeur:
    float htonf(float a)
    {
    	uint32_t const ret = htonl(*reinterpret_cast< uint32_t const * >(&a));
    	return *reinterpret_cast< float const * >(&ret);
    }

    Et puis, devant l'absence de defines standard universels pour l'endianness, quand je me retrouve à réimplémenter htons() par exemple, je fais plutôt ceci:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    uint16_t htons(uint16_t a)
    {
    	char const ret[2] = { (a >> 8) & 0xFF, a & 0xFF };
    	return *reinterpret_cast< uint16_t const * >(ret);
    }
    Comme ça, c'est indépendant de la véritable endianness du système.
    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.

  14. #14
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Pourquoi ne pas passer par un encodage BER ou similaire, dans ce cas ? Ca garantit la portabilité.

  15. #15
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    htonl va refaire exactement ce que j'ai fait plus haut, donc c'est un intermédiaire inutile.
    Et en plus, ton code doit briser les règles d'aliasing strictes.
    Boost ftw

Discussions similaires

  1. [VBA-E] Comment faire une fonction utilsant une autre feuille
    Par EvaristeGaloisBis dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 12/04/2007, 16h27
  2. Comment faire une fonction - procédure
    Par Madmac dans le forum C
    Réponses: 14
    Dernier message: 12/08/2006, 09h57
  3. Comment faire une fonction qui renvoi un tableau.
    Par poly128 dans le forum Delphi
    Réponses: 2
    Dernier message: 01/06/2006, 01h04
  4. [C#][Débutant] Comment faire une fonction FindWindow ?
    Par Cazaux-Moutou-Philippe dans le forum Windows Forms
    Réponses: 4
    Dernier message: 27/04/2006, 13h19
  5. [VB6] Comment faire une fonction qui renvoie 2 résultats
    Par tazarine dans le forum VB 6 et antérieur
    Réponses: 10
    Dernier message: 15/01/2004, 00h13

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