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 un type REAL 6 octets (PASCAL) en float 4 octets


Sujet :

C++

  1. #1
    Membre habitué
    Inscrit en
    Février 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 9
    Par défaut Convertir un type REAL 6 octets (PASCAL) en float 4 octets
    Bonjour,


    Voilà je lis un fichier binaire qui a été réalisé par une application dévellopé en pascal.Dans ce fichier binaire, il a des variable de type "Real" qui ont donc une taille de 6 octets.

    Le probleme c'est que je n'ai pas de type de variable en c++ avec une taille de 6 octets. (float-> 4 octets, double-> 8 octets) .


    CFile INFILE(FichierBinALire,CFile::typeBinary | CFile::modeRead | CFile::shareDenyNone) ; // ouverture en lecture d'un fichier binaire

    INFILE.Read(&m_bypremierOctet,1); //type BYTE 1 octet
    INFILE.Read(&m_bydeuxiemeOctet,1); // type BYTE 1 octet
    INFILE.Read(&m_ctroisiemeOctet,1); // type char 1 octet



    INFILE.Read(& ????????????????????????,6);// COMMENT FAIRE SVP ??



    INFILE.Close(); //fermeture

    En conclusion : Comment puis je lire une variable de taille 6 octets en c++ ????

    Merci beaucoup !
    Au faite, je suis débutant.....!!
    Merci beaucoup

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2004
    Messages : 54
    Par défaut
    perso, j'essaierai un truc du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    //...
    char tmp[8];
    Read(tmp, 6);
    double res = *(reinterpret_cast<double*>(tmp));
    En espérant que ça marche

  3. #3
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Hio,
    Citation Envoyé par bountykiller
    perso, j'essaierai un truc du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    //...
    char tmp[8];
    Read(tmp, 6);
    double res = *(reinterpret_cast<double*>(tmp));
    En espérant que ça marche
    Ça ne marchera pas.

    Comment veux-tu que ton compilateur devine le format des réels sur 6 octets du Pascal ?

    Je vois 2 solutions "simples"

    - En Pascal, tu relis le fichier et tu en crées un autre, soit binaire (en remplaçant le type Real (6 octets) par le type double ou float (idem des C/C++), soit au format texte (je préfère cela, ça évitera les éventuels problèmes d'alignement des données dans la structure).

    - un peu plus compliqué : tu cherches la définition du format du type réel su 6 octets du Pascal, et tu te fais une petite fonction pour convertir ves float ou double.

  4. #4
    Membre habitué
    Inscrit en
    Février 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 9
    Par défaut
    Bonjour,

    Tout d'abord,je tiens à vous remercier pour les réponses apportées.

    Pour bountyKiller -> j'ai déjà essayé cette solution mais cela me marche pas ça me donne n importe quoi.

    Pour droggo -> j'aimerai effectivement convertir le type "Real"(6 octets) du pascal en "float"(4 octets) du c++ en utilisant ta 2e proposition qui me paraît la mieux adapté à mon problème en créant un fonction de conversion.

    D'aprés les informations sur internet concernant les formats , on a :

    Pour le type real du pascal : il est codé sur 48 bits ( 6 octets)

    -> 1er bit pour le signe taille: 1 bit
    -> du 2e bit au 8e bit pour l'exposant taille: 7 bits
    ->du 9e bit au 48e bit pour la mantisse taille: 40 bits

    Pour le type float du c++ : il est codé sur 32 bits ( 4 octets)

    -> 1er bit pour le signe taille: 1 bit
    -> du 2e bit au 9e bit pour l'exposant taille: 8 bits
    ->du 10e bit au 32e bit pour la mantisse taille: 23 bits


    Dans mon fichier binaire, je dois lire quand même 6 octets, sur quelle type de variable puis je les stocker ???

    Et puis le plus important, je dois savoir comment on lit un bit et comment on ecrit un bit en c++ !

    En conclusion j aimerais :

    1)lire les 6 octets dans un fichier binaire
    2) lire les 32 bits qui m'interresse sur ces 48 bits
    3)ecrire ces 32 bits pour donner la valeur à ma variable de type float

    j imagine un fonction de convertion real en float du type :

    ConvertRealToFloat( type6Octets??? MaVarReal, float& maVar)
    {

    .....

    .....???


    }

    En tous cas, merci beaucoup d'essayer de me répondre !

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Août 2005
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 14
    Par défaut
    salut,

    Si tu veux une solution simple :
    avec une routine écrite en pascal , crée un fichier texte par exemple une ligne pour chaque réel,
    puis avec une routine en c++ , tu lit le fichier texte et tu converti le chaines de caractères en float.
    a+

  6. #6
    Membre habitué
    Inscrit en
    Février 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 9
    Par défaut
    bonjour,

    Mecri pour la réponse.En fait mon application fonctionne en même temps que l 'application dévelloppé en pascal.

    L'application en pascal crée un fichier bin des trames de 783 octets, et moi je cré un fichier txt avec des donnees que je mets plus des données qui me faut récuperer en temps réel sur le fichier bin.

    Je ne peux absolument pas touché a l'application dévellopé en pascal, en effet, il suffisait par exemple de remplacer le type Real en pascal par string dans le code source , mais dommage je ne peux pas !

    Je ne pense pas que ajouté une 3 e application (la routine) qui tourne en même temps que les 2 autres serait bien !

    Je cherche tout simplement un moyen de convertir un "real" (pascal) en "float" .Je pense sincçèrement que la meilleur methode est de comparer le codage de ces 2 formats (signe,exposant,mantisse), et de mettre en place une fonction pour une lecture / ecriture bit par bit...comme dis précédement.

    Au fait, en plus je ne connais du tout le pascal!!

    En tout cas merci beaucoup pour vos réponses, en espérant que quelqu'un puisse apporté un peu de lumière à ce problème !!!

    A bientôt !!!

  7. #7
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Jao,

    Pour lire 6 octets en c++, tu peux tout simplement lire un char[6], (ça va sûrement faire hurler quelques puristes, mais il faut faire avec).

    Un fois lus, tu transtypes dans un champ de bits, et tu n'as plus qu'à faire la conversion, en prenant quand même la précaution de vérifier le format des réels 6 octets, en particulier le format des bits donnant l'exposant.

  8. #8
    Membre habitué
    Inscrit en
    Février 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 9
    Par défaut
    bonjour,


    Excuse moi droggo pourrait me détailler ta réponse, s'il te plaît, car je débute et le codage des formats ne m'est pas familier. J'aimerais tous simplement un exemple explicite.

    Je reprends ici ;

    char maVariableReal[6] ; // Variable pour stocker mes 6 octets, là j'ai compris !

    CFile INFILE(FichierBinALire,CFile::typeBinary | CFile::modeRead | CFile::shareDenyNone) ; // ouverture en lecture d'un fichier binaire

    ..........

    INFILE.Read(maVariableReal,6);// je lis mes 6 octets de la variable real et je les stocke dans maVariableRea , ça je crois que c'est bon

    ........

    INFILE.Close(); //fermeture du fichier binaire

    // S'IL VOUS PLAÎT C'EST A PARTIR DE MAINTENANT QUE JE SUIS PERDUS !

    float maVariableFloat ; // 4 octets

    maVariableFloat = (transtyper le champ de bits ???) *maVariableReal ???


    Excuse moi, droggo , j'ai vraiment besoin d'un exemple concret pour que je comprenne, je suis qu'un petit débutant !

    En tous cas merci beaucoup !

  9. #9
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Loa,

    Désolé stufynice, mais j'ai cherché le format exact du type real sur 6 octets.

    J'en ai trouvé une différente de celle que tu donnes, et pour l'instant je n'arrive pas à convertir correctement, que ce soit avec l'une ou l'autre.

  10. #10
    Membre habitué
    Inscrit en
    Février 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 9
    Par défaut
    bonjour,

    Merci beaucoup droggo pour ta tentative !

    je voulais juste joindre 2 fichiers binaires, monfloat.bin où il y a la valeur d' un float écris en c++ ( 4 octets)

    Et monReal.bin où il y a un type real (6 octets) ecris en pascal.

    Le valeur est 13.13 pour les 2 !

    En fait je me permets de le rappeler, le but du jeu est de lire la valeur 13.13 dans un float ( ou double peu importe) avec le fichier real.bin en c++.

    Un grand merci à vous !

    A bientôt !
    Fichiers attachés Fichiers attachés

  11. #11
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Foa,

    Voilà, j'ai trouvé un exemple sur le web, qui contenait quelques petites erreurs.

    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    #include <iostream>
    #include <math.h>
     
    using namespace std;
     
    const size_t indMax = 5;
    const size_t indMaxSize = indMax +1;
     
    typedef unsigned char uint_8;
    typedef uint_8 tab_u8[indMaxSize];
     
    //========================================
    // conversion d'un real 6 octets en double
    // d'après un code trouvé sur le web
    // corrigé de quelques petites erreurs
     
    double r6ToFloat(tab_u8 & t)
    {
        double res = 0.0; // contiendra le résultat
     
        // si l'octet d'indice 0 = 0, alors résultat = 0,
        // donc, on ne continue que s'il est != 0
        if (t[0] != 0)
        {
            int exposant = t[0] - 129;
            int signe = (t[5] & 0x80) == 0 ? 1 : -1;
     
            // mantisse. On initialise avec t[5] d'où
            // on exclu le bit de signe (bit 8)
            res = t[5] & 0x7F;
            // et on ajoute les données des 4 autres
            // octets de la mantisse
            for (int i=4; i>0; --i)
            {
                res*= 256;
                res+= t[i];
            }
            // après cela, il faut rediviser la mantisse par
            // 256 puissance 5
            for (int i=1; i<=5; ++i)
            {
                res/= 256;
            }
            // et il reste quelques ajustements à faire
            res *= 2;
            res += 1;
            res *= pow(2.0L,exposant);
            res *= signe;
        }
     
        return res;
    }
     
    int main()
    {
        FILE *f = NULL;
        f = fopen("monreal.BIN","rb");
        if (f != NULL)
        {
            // ouverture du fichier ok
     
            // tab va recevoir les données du fichier
            tab_u8 tab;
            size_t lus = fread(&tab,1,indMaxSize,f);
            if (lus != indMaxSize)
            {
                // mauvaise lecture
                cout << "mauvaise lecture" << endl;
            }
     
            // et conversion
     
            float res = r6ToFloat(tab);
            cout << "la conversion donne : "<<res<<endl;
     
            int clos = fclose(f);
            if (clos != 0)
            {
                // echec fermeture du fichier
                cout << "echec fermeture du fichier" << endl;
            }
        }
        else
        {
            // echec ouverture du fichier
            cout << "echec ouverture du fichier" << endl;
        }
     
     
    	return EXIT_SUCCESS;
    }
    résultat de l'exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    la conversion donne : 13.13

  12. #12
    Membre habitué
    Inscrit en
    Février 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 9
    Par défaut
    Bonsoir droggo,

    Merci beaucoup pour ton aide ! je ne peux pas le tester ce soir, je le fais dès demain !

    Puis si ça fonctionne, je travaillerais dessus pour bien comprendre pourquoi on fais comme ça !

    En tous cas ,le code est bien lisible (commenté) ça sera un plaisir !

    Encore merci à toi droggo !Et à tous les dévellopeurs !

    Bonne soirée !

  13. #13
    Membre habitué
    Inscrit en
    Février 2006
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 9
    Par défaut
    Bonjour ,


    Merci droggo! la conversion que je cherchais fonctionne trés bien !

    A bientôt !

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

Discussions similaires

  1. convertir un type octet-string
    Par Cedrci35 dans le forum WinDev
    Réponses: 6
    Dernier message: 24/03/2010, 09h43
  2. Convertir le type d'un champ
    Par mat75019 dans le forum Access
    Réponses: 2
    Dernier message: 21/04/2006, 11h49
  3. [MS SQL] Est il possible de forcer la précision du type REAL
    Par TEXMEX dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 03/04/2006, 17h31
  4. [LG]Convertir le type double en string
    Par @tom@ dans le forum Langage
    Réponses: 8
    Dernier message: 18/01/2004, 19h20
  5. Convertir un type de donnée sous SQL Server
    Par Fleep dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 19/08/2003, 15h15

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