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 :

convertir des octets en float : format apparement specifique


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut convertir des octets en float : format apparement specifique
    Re !
    C'est encore moi et mon fichier 3ds ^^
    Je dois convertir des octets en un float mais ça n'a pas l'air si simple que ça.
    J'ai regardé un peu comment sous pc et mac les floats etaient placés en memoire mais c'est encore pire que ce que je pouvais penser ^^
    En gros, je ne comprend pas comment en recuperant 4 octets on peux les replacer en float.
    Ce qui est certain, c'est que entre pc et mac il y a une difference (endianess ? taille des floats ?)

    Quelqu'un aurait-il une info la dessus svp ? j'ai essayé de regarder sur le net le principe de codage hexa d'un reel non signé, et à vrai dire je n'ai pas tout compris. Ils parlent du signe à droite du bit de poids fort, une mantisse et un exposant. Bon ok, mais ils ne disent pas ou se trouve la mantisse ni l'exposant donc je ne peux pas faire d'essai

    Merci d'avance
    @++

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Regarde la norme IEEE 754 (si je me souviens bien) pour une description détaillée de l'encodage des flottants. Par contre étant donné que c'est normalisé j'imagine que tous les systèmes utilisent ce même encodage non ?

  3. #3
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Non, il n'y a rien de bien défini, tu peux trouver des systèmes qui auront peut être un codage différent pour les réels.

  4. #4
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Loulou24
    Regarde la norme IEEE 754 (si je me souviens bien) pour une description détaillée de l'encodage des flottants. Par contre étant donné que c'est normalisé j'imagine que tous les systèmes utilisent ce même encodage non ?
    La norme ne detaille pas l'encodage. Il y en a au moins 3 d'utilises (et deux d'entre eux ne different que pour les NaN)

    Je suis cependant surpris que PowerPC ne soit pas simplement les meme bytes qu'un x86 dans un autre ordre. zax-tfh, peux-tu donner le resultat de ce programme sur tes deux plateformes?

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    #include <iostream>
    #include <climits>
    #include <cfloat>
     
    template <typename T>
        std::string toBitGroup(T const& value, int bitPerGroup)
    {
      static int const maxResultSize = sizeof(T)*CHAR_BIT + 1;  
      char result[maxResultSize];
      unsigned char const* raw = reinterpret_cast<unsigned char const*>(&value);
      unsigned char carry = 0;
      int bitsInCarry = 0;
      int resIndex = maxResultSize;
     
      result[--resIndex] = '\0';
      for (int rawIndex = sizeof(T)-1; rawIndex >= 0; --rawIndex) {
        while (bitsInCarry + CHAR_BIT >= bitPerGroup) {
          if (bitsInCarry >= 0)
            carry |= raw[rawIndex] << bitsInCarry;
          else
            carry |= raw[rawIndex] >> -bitsInCarry;
          result[--resIndex]
            = "0123456789ABCDEF"[carry & 0xF & (~(0xF << bitPerGroup))];
          carry >>= bitPerGroup;
          bitsInCarry -= bitPerGroup;
        }
        bitsInCarry += CHAR_BIT;
      }
      if (bitsInCarry > 0) {
        result[--resIndex]
          = "0123456789ABCDEF"[carry & 0xF & (~(0xF << bitPerGroup))];
      }
      return result+resIndex;
    }
     
    int main(int argc, char *argv[]) {
        std::cout << toBitGroup((double)0.0, 4) << '\n';
        std::cout << toBitGroup((double)DBL_MIN, 4) << '\n';
        std::cout << toBitGroup((double)-DBL_MIN, 4) << '\n';
        std::cout << toBitGroup((double)0.125, 4) << '\n';
        std::cout << toBitGroup((double)-0.125, 4) << '\n';
        std::cout << toBitGroup((double)0.25, 4) << '\n';
        std::cout << toBitGroup((double)-0.25, 4) << '\n';
        std::cout << toBitGroup((double)0.5, 4) << '\n';
        std::cout << toBitGroup((double)-0.5, 4) << '\n';
        std::cout << toBitGroup((double)1.0-DBL_EPSILON, 4) << '\n';
        std::cout << toBitGroup((double)1.0, 4) << '\n';
        std::cout << toBitGroup((double)1.0+DBL_EPSILON, 4) << '\n';
        std::cout << toBitGroup((double)2.0, 4) << '\n';
        std::cout << toBitGroup((double)4.0, 4) << '\n';
        std::cout << toBitGroup((double)0xFF6E5D+(double)0x9876543/0x20000000, 4) << '\n';
        std::cout << toBitGroup((double)DBL_MAX, 4) << '\n';
        std::cout << toBitGroup((double)-DBL_MAX, 4) << '\n';
    }
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  5. #5
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par PRomu@ld
    Non, il n'y a rien de bien défini, tu peux trouver des systèmes qui auront peut être un codage différent pour les réels.
    Il y a deux choses:

    Premierement, rien n'impose l'utilisation de IEEE-754 mais en pratique hors les descendants de machines anterieure a 1985, on ne trouve guere que ca. Une classe toujours importante de descendants de machines anterieure a 1985, c'est les descendants des IBM 360 (zSeries? je suis perdu dans cette nomemclature) bien qu'ils ont aussi des flottants IEEE-754. Une classe historiquement importante, c'est les differents formats des VAX, mais il me semble que l'interet n'est plus qu'historique. Quelque chose qui va peut-etre avoir une importance, c'est les flottants decimaux -- bien que je n'en ai jamais compris l'interet profond, IBM fait pas mal de lobbying autour. A ma connaissance, les processeurs en question ici se reclame de la norme IEEE-754.

    Deuxiement, IEEE-754 ne detaille pas une representation binaire bien qu'un schema ou l'autre en suggere fortement une. En pratique on utilise la variante big endian et little endian de cette representation. Mais vient se greffer le probleme des NaN signalant/silencieux et la aussi il y a de la variation sans qu'il y ait une suggestion dans le texte. Au total je connais 3 representations utilisees.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Re !

    Alors voila le resultat mac :

    [Session started at 2006-01-12 14:36:07 +0100.]
    0000000000000000
    0010000000000000
    8010000000000000
    3FC0000000000000
    BFC0000000000000
    3FD0000000000000
    BFD0000000000000
    3FE0000000000000
    BFE0000000000000
    3FEFFFFFFFFFFFFE
    3FF0000000000000
    3FF0000000000001
    4000000000000000
    4010000000000000
    416FEDCBA9876543
    7FEFFFFFFFFFFFFF
    FFEFFFFFFFFFFFFF

    test float has exited with status 0.
    Le resultat pc dans le prochain post dans trentes secondes ^^

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    resultat pc :

    0000000000000000
    0000000000001000
    0000000000001080
    000000000000C03F
    000000000000C0BF
    000000000000D03F
    000000000000D0BF
    000000000000E03F
    000000000000E0BF
    FEFFFFFFFFFFEF3F
    000000000000F03F
    010000000000F03F
    0000000000000040
    0000000000001040
    436587A9CBED6F41
    FFFFFFFFFFFFEF7F
    FFFFFFFFFFFFEFFF
    Ce qui est bizarre, c'est que le gars dans son loader de fichier 3ds, il ne se prend pas la tete avec tout ça...
    Voici comment il procede (bon c'est sur il ne tient pas compte de l'endian)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sommet->m_fCoord[0] = *(float *)&m_ucpBuffer[0];
    m_ucpbuffer etant son tableau de caracteres contenant ses octets lus dans son fichier.

    Voilou

    je continue de nager moi ^^

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Je crois que je finis par comprendre à peu pres, par rapport aux resultats... faut que je continue à regarder et si je trouve une réponse, je la posterai ici. En attendant, je continue de chercher ^^

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Nan en fait je comprend rien ^^
    Voici entre guillemets ma logique de pseudo debutant (ou plutot d'ignare en matiere de codage de types :

    Je lis 4 octets dans mon buffer :
    buff[0] buff[1] buff[2] buff[3]

    Si je fais un sizeof(float) j'obtiens 4, donc un float est codé en 4 octets (du moins si on part sur une base de test sans chercher la portabilité ou autre vu que le float ne sera peut etre pas codé sur 4 octets partout, j'en sais rien).

    Donc on à 4 octets d'un coté et on peut en placer 4 dans un float. Donc logiquement, soit on les place dans l'ordre soit on les place dans le sens inverse et on devrait retrouver nos billes... avec un decalage bien sur, de 8 par 8 bits.
    Mais en phase de test ça ne fonctionne pas

    Donc là c'est vraiment de la semoule liquide dans laquelle je nage ^^

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Bon ça fait toute une journée complete à chercher sur le sujet, je commence à saturer

    J'ai retourné le probleme dans tous les sens mais je ne trouve toujours pas de solution...
    Par contre j'ai des questions :

    Imaginons un float ayant pour valeur 0xAABBCCDD
    Cette valeur est inscrite dans cet ordre dans le fichier 3ds.
    Si l'endian change vis à vis de cette valeur et donc de l'endian d'origine qui a inscrit le float dans le fichier.
    Est-ce que mon float retranscrit dans l'endian courant aura bien pour valeur 0xDDCCBBAA ?
    Je demande ça car vis à vis du format d'un float ça change completement la place des choses, notamment la place du bit de signe qui au lieu de se retrouver au 32 bit se retrouve finalement au 8eme.
    De là decoule deux autres questions :
    - soit le systeme le gere, dans quel cas une simple inversion des octets suffit (j'ai testé ça passe pas )
    - soit le systeme ne le gere pas et donc il faut retranscrire le float dans un format lisible... dans quel cas je ne sais pas comment faire

    Une question finale :
    Sachant que l'on a ceci :

    vector<unsigned char> buffer

    Et que l'on souhaite recuperer 4 octets du buffer, comment feriez vous pour transformer ces 4 octets en un float adapté au systeme (endian et taille du float) ?

    Merci d'avance
    ++

  11. #11
    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
    Pour information, dans un document non officiel sur les fichiers 3ds , j'ai lu que les float étaient effectivement codés en format IEEE sur 4 octets. Il ne précise pas l'endianess. C'est probablement celle des PC, le logiciel 3D Studio n'était pas je crois (au moins à l'origine) disponible sur Mac.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    merci diogene, je l'avais plus ou moins deviné vu que le reste l'est aussi (je parle de l'endianess).
    Pour ce qui est des 4 octets, idem, j'avais lu sur une doc que c'etait codé sur 4 octets. Pour ce qui est du IEEE, je ne sais pas comment en tirer quelque chose en fait

    Merci pour la precision en tout cas

  13. #13
    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
    Et que l'on souhaite recuperer 4 octets du buffer, comment feriez vous pour transformer ces 4 octets en un float adapté au systeme (endian et taille du float) ?
    Si on veut que ce soit indépendant de la plateforme, il faut recalculer la valeur à partir des octets:
    En little endian,
    - Le premier octet O1 (unsigned char) contient les bits de la mantisse de poids 2^-16 à 2^-23. sa contribution à la mantisse m est O1/8388608.0

    - le second octet O2 (unsigned char)les bits de la mantisse de poids 2^-8 à 2^-15 sa contribution à la mantisse est O2/32768.0

    - le troisième octet O3 (unsigned char) après mise à 1 du poids fort (-> O'3) les bits 2^0 à 2^-7 sa contribution à la mantisse est O'3/128.0
    La mantisse m est la somme de tout ça;

    - Le bit de poids fort de cet octet O3 est le bit de poids faible de l'exposant. Le quatrième octet O4 (unsigned char) a pour poids fort le signe 0 pour + et 1 pour -
    Après élimination du bit de poids fort par décalage et insertion en poids faible du bit de poids fort de O3 (->O'4), on a l'exposant biaisé de 127.
    Retouver l'exposant par int exp = O'4-127
    Multipler la mantisse m par 2^exp
    Si le bit de poids fort de O4 est 1, changer de signe

    OUF

    Edit : le cas de la valeur 0 est particulier (tous les octets à 0)
    ceci suppose que le fichier ne contient pas de valeurs exotiques style NaN INF ou des nombres dénormalisés
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Très interressante ta decomposition Diogene ! je vais travailler ça demain je pense ^^

    Par contre, un truc qui me vient à l'esprit direct, si on recompose ce que tu dis, ça nous donne la description du format d'un float, ok ?
    1bit pour le signe, 8 pour l'exposant et 23 pour la mantisse.
    Or si on recompose le float je dirais de maniere barbare c'est à dire en obligeant le format du float en 4 octets (comme sur mon systeme actuel) et selon un endian précis (comme celui de mon systeme), normalement je devrais retrouver mon float non ?

    Or j'ai fait le test suivant :

    une fonction de test qui est censée recomposer mes 4 octets et transformer tout ça en float. j'ai testé les deux methodes (celle en commentaire et celle qui ne l'est pas, en essayant les deux endian également)

    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
    float readFloat(vector<unsigned char>buff, int debut, int fin)
        { 
        float result = 0;
    	/*result = result * 0x100 + buff[debut+1];
    	result = result * 0x100 + buff[debut+2];
    	result = result * 0x100 + buff[debut+3];*/
     
    	char toto[4];
    	toto[0] = buff[debut+3];
    	toto[1] = buff[debut+2];
    	toto[2] = buff[debut+1];
    	toto[3] = buff[debut];
    	result = *((float*)toto);
        return result; 
        }
    Code appelant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    x = readFloat(buffer, position_x, position_x + 3);
    Je me retrouve tout le temps avec un nombre abhérent quelque soit la methode essayée...

    Franchement je ne vois pas...
    Merci pour ton explication en tout cas Diogene !

  15. #15
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Quelque chose qui va peut-etre avoir une importance, c'est les flottants decimaux -- bien que je n'en ai jamais compris l'interet profond, IBM fait pas mal de lobbying autour.
    N'est-ce pas parce que pour les calculs financiers, il permettent des calculs d'arrondis conformes aux lois, chose que les flottants ne font pas ?
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  16. #16
    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
    Par contre, un truc qui me vient à l'esprit direct, si on recompose ce que tu dis, ça nous donne la description du format d'un float, ok ?
    Oui
    1bit pour le signe, 8 pour l'exposant et 23 pour la mantisse.
    Oui
    Tout dépend si tu veux une indépendance vis à vis de la pateforme. Dans ce cas, il faut recalculer : style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    float mantisse = tab[0]/8388608.0;
    mantisse += tab[1]/32768.0;
    ....
    Sinon, si la plateforme cible est spécifique (et IEEE), il suffit effectivement de replacer les octets dans le bon ordre selon l'endian de la plateforme.
    Dans ton cas, les fichiers que tu lis possèdent des chunk qui décrivent la nature des blocs de données. Es tu sùr que tu ne te trompes pas dans leur gestion et que les données que tu essayes de lire sont bien des float ? Il suffit de se tromper d'un octet sur leur position dans le fichier et tout est foutu
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  17. #17
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par JolyLoic
    Citation Envoyé par Jean-Marc.Bourguet
    Quelque chose qui va peut-etre avoir une importance, c'est les flottants decimaux -- bien que je n'en ai jamais compris l'interet profond, IBM fait pas mal de lobbying autour.
    N'est-ce pas parce que pour les calculs financiers, il permettent des calculs d'arrondis conformes aux lois, chose que les flottants ne font pas ?
    Les lois que je connais demandent un calcul infiniment précis suivi d'un arrondi, ce que ne permettent pas les flottants qu'ils soient décimaux ou binaires. La précision nécessaire est généralement calculable a priori et donc une représentation en virgule fixe suffit et les flottants n'apportent rien qu'une consommation de bits inutile; pour autant qu'ils soient utilisables parce qu'il y a un risque de double arrondi. Il y a quelques cas où la précision nécessaire n'est pas facilement calculable a priori et donc les représentations en virgule fixe ne sont pas utilisables; mais alors si on veut faire un calcul exact -- je ne suis pas sûr que la loi le demande dans ces cas parce qu'on ne saurait le faire à la main de toute façon, il faut évaluer des fonctions transcendantes jusqu'à ce qu'on puisse les arrondir correctement -- il faut taper dans les bibliothèques de précision non bornée parce qu'à nouveau, les flottants n'aident pas.

    Le seul avantage des flottants décimaux, c'est de conserver précisément les données décimales. Au prix d'une perte de précision et -- d'après les numériciens -- de difficultés d'analyse. Mais si les données décimales sont exactes et qu'il faut des calculs exacts, une représentation en virgule fixe ou une représentation à précision non bornée conviendrait vraissemblablement mieux. Si ce n'est pas le cas, les flottants binaires sont plus précis.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    YES !!!!!
    Ca y est ! ça fonctionne enfin !
    Alors voilà comment j'ai procédé, mais avant tout je tiens à remercier Diogène qui a terminé le traçage du chemin que ceux avaient commencé à me montrer (et je les en remercie aussi !)
    Donc en gros, je me suis dit : Diogene souleve un lapin qui en effet n'est pas négligeable. Est-ce que je suis sur les bons octets ?
    Je me suis dit, bah le soucis c'est que pour tester, bah faut bien parcourir le fichier, j'ai pas le choix. Sauf que m'est venue l'idée de faire un petit script qui va inscrire un float dans un fichier en binaire (à la façon de l'exemple de la FAQ C++ "comment lire/ecrire dans un fichier binaire".

    J'ai fait mes essais, puis ensuite j'ai adapté ma technique de lecture de float avec mon tableau de caracteres (pas tres joliement fait mais c'etait pour le test). Et ça a marché ! donc ni une ni deux, je réadapte sur mon code pour mon fichier 3ds et là, c'est le drame... toujours rien...
    Bon comme me disais Diogène, je ne dois pas etre au bon octet... Je vérifie par rapport à la doc que j'ai trouvé sur le net, et si j'y etais bien.... Mais je me suis souvenu que j'avais une autre doc, en english cette fois et genre le bon vieux fichier texte tout pourri ou ils ont pris un texte, melangé les caracteres et versé tout ca dans un tite boite tellement c'est pas tres lisible... lol. Et là, c'est le drame... Juste avant le chunk de mes floats, il y a un chunk pour lire le nombre de vertexs que je dois recuperer. Dans la doc française, il était écrit 4 octets... dans l'anglaise 2.... Donc voila d'ou ca venait... J'aurais pu tourner pendant des jours entiers sans pour autant trouver la réponse à ma question !

    Enfin voila ! tout est bien qui fini bien et je dirais qu'au moins cette aventure m'aura permis d'apprendre encore de nouvelles choses !
    Merci encore à tous pour votre patience et votre dévouement c'est vraiment sympa !

    @ bientot !

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    C'est re-moi, bon certes ça fonctionne avec la fonction test que j'ai fait mais c'est pas terrible quand meme...
    Et y'à un truc que je ne saisis pas vraiment. J'ai essayé plusieurs méthodes et seule celle que j'ai fait avec le tableau de char fonctionne...

    Voici le code :

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    float readFloat(vector<unsigned char>buff, int debut, int fin)
        { 
    	float result = 0;
     
    	//1ere methode decalage barbare (fonctionne pas)
    	//result = (buff[debut+3] * 0x1000000) + (buff[debut+2] * 0x10000) + (buff[debut+1] * 0x100) + (buff[debut]);
     
    	//2eme methode decalage recursif (non plus)
    	/*
    	result = buff[debut]; 	
    	if(debut<fin)
    		result = readFloat(buff, debut+1, fin) * 0x100 + result;
    	*/
     
    	//3eme methode tableau de char et cast en float. (fonctionne mais pas pratique...)
        /*
    	char toto[4];
     
    	if (0)
    		{
    		//PC
    		toto[0] = buff[debut];
    		toto[1] = buff[debut+1];
    		toto[2] = buff[debut+2];
    		toto[3] = buff[debut+3];
    		}
    	else
    		{
    		//MAC
    		toto[0] = buff[debut+3];
    		toto[1] = buff[debut+2];
    		toto[2] = buff[debut+1];
    		toto[3] = buff[debut];
    		}
    	result = *((float*)toto);
    	*/
     
        return (float)result; 
        }
    La premiere et deuxieme methode est la meme que pour renvoyer un long ou autre. Elle fonctionne très bien pour les long sur les deux OS/archi. Par contre en float je ne comprend pas, ça ne passe pas.
    Pourtant, logiquement c'est censé remettre les octets dans l'ordre d'après l'endianess de la machine, chose qui se fait nickel pour les long avec cette meme méthode.
    Mais alors, pourquoi ça ne passe pas avec les floats ?

    C'est encore trop bizarre comme histoire ça....
    Si vous avez une idée, n'hesitez pas
    Merci !

  20. #20
    Membre habitué
    Avatar de superspag
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    153
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 153
    Points : 186
    Points
    186
    Par défaut
    Tu peux tenter un truc comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    union FloatOct         
    { 
      float valfloat; 
      struct {  
        unsigned char oct3 : 8; 
        unsigned char oct2 : 8; 
        unsigned char oct1 : 8; 
        unsigned char oct0 : 8; 
      };
    };
    Je ne sais pas si ça marche, je n'ai pas le temps de faire des tests... ça devrai etre bon à l'ordre prés des octn

    J'explique quand même : c'est le même principe que les champs de bits. Ici je declare une structure que j'interprete soit comme un float, soit comme 4 octets.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    FloatOct test;
    test.valfloat = 15.61;
    ...
    ...test.oct0...
    ...
    Je donne ainsi une valeur float et je peux recuperer les octets par la suite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    FloatOct test;
    test.oct0 = ...;
    test.oct1 = ...;
    test.oct2 = ...;
    test.oct3 = ...;
    ...
    ...test.valfloat...
    ...
    De la même manière, je donne les valeurs à chacun de mes octets et je recupere par la suite la valeur float.

    Dite moi si ça marche, ça m'interesse ^^
    Plus y'a d'Gruyère, plus y'a d'trous !
    Plus y'a d'trous, moins y'a d'Gruyère...
    Donc, Plus y'a d'Gruyère, moins y'a d'Gruyère !!!

Discussions similaires

  1. [Toutes versions] Questions pour convertir des nombres stockés en format texte
    Par antoisse3 dans le forum Excel
    Réponses: 7
    Dernier message: 20/04/2015, 09h55
  2. Convertir des chiffres format texte en vrai chiffre?
    Par Bertrand57 dans le forum Excel
    Réponses: 4
    Dernier message: 09/04/2008, 21h16
  3. Fonction pou de convertire des MIN en format HH:MM
    Par Rifton007 dans le forum Windows Forms
    Réponses: 5
    Dernier message: 27/06/2007, 18h07
  4. Convertir des formats musicaux en langage C
    Par la_praline dans le forum C
    Réponses: 14
    Dernier message: 21/05/2007, 10h00
  5. convertir un string en float avec un format
    Par kisscool62 dans le forum C++/CLI
    Réponses: 2
    Dernier message: 04/12/2006, 14h13

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