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 Réel Simple ou Double du DOS


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 23
    Par défaut Convertir un Réel Simple ou Double du DOS
    Bonjour,

    je chèrche à récupérer des données d'un vieux logiciel écrit en GW Basic.
    ce sont des bases de données à accés aléatoire.
    j'arrive à récuperer les chaines, mais pas les réels.

    je m'explique :
    j'importe des données qui sont la suite de codes AscII suivante :
    0 0 0 129 => je sait que ça corresponds à 1,00

    Or si je déclare un Réel, et que je lui affecte la valeur 1, ça me donne en mémoire : 0 0 128 63.

    donc à priori, les réels sur 4 octets ne sont pas codés de la même manière en gwBasic. savez-vous comment je peut convetir mon réel ?
    Indication : l'instruction servant à récupérer les données en GWBasic sont :
    CVI() pour les entier
    CVS() pour les Réels simple sur 4 octet
    CVD() pour les Réels Doubles sur 8 Octet.

    Dur dur... Merci quand même.

  2. #2
    Expert confirmé
    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
    Par défaut
    Note : dans ce qui suit "a^^b" signifie "a puissance b"

    Le format de codage présente des similitudes et des différences (position du bit de signe et biais de l'exposant).

    La mantisse M et l'exposant E sont tels que le nombre F (#0) peut s'écrire F = M 2^^E avec 1 >M>=0.5 Sauf pour 0, la mantisse en binaire commence toujours par 0.1... Ce 1 (de poids 2^^-1) est implicite et donc le bit n'est pas codé (mantisse réduite)

    D'après ce que j'ai trouvé ici , dans le document GW-MAN.ZIP Appendix D, section D3, en GWBasic, les 4 octets utilisés pour coder un float sont
    - 1 Les bits de poids faibles de la mantisse réduite
    - 2 Les bits de poids intermédiaires de la mantisse réduite
    - 3 Les 7 bits de poids fort de la mantisse réduite et en poids fort de l'octet le bit de signe ( 0 = positif)
    - 4 L'exposant avec un biais de 128

    Dans l'exemple, ceci donne 1 = 0.5x2^^1
    L'exposant+ le biais = 129
    La mantisse réduite est 0
    le bit de signe est 0 et la mantisse réduite étant 0, les trois autres octets sont 0.
    D'où le code 0 0 0 129

    Dans ton code C, on a
    - 1 Les bits de poids faibles de la mantisse réduite
    - 2 Les bits de poids intermédiaires de la mantisse réduite
    - 3 Les 7 bits de poids fort de la mantisse réduite et en poids fort de l'octet le bit de poids faible de l'exposant (biaisé)
    - 4 Le reste de l'exposant biaisé par 126 et en poids fort de l'octet le bit de signe

    Dans l'exemple, ceci donne 1 = 0.5x2^^1
    L'exposant biaisé 126+1 =127(=0111 1111)
    La mantisse réduite 0
    Le signe (0) + les 7 bits de poids forts de l'exposant biaisé donne 00111111 soit 63
    Le bit de poids faible de l'exposant (1) suivi de la mantisse réduite (0) donne 10000000 soit 128
    d'où le code 0 0 128 63

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 23
    Par défaut
    Bonjour,

    Merci pour votre réponse.

    J'ai trouvé d'autres infos :

    le GW basic codait ses flotants avec la norme MBF (Microsoft Binary Float)
    puis en 1985 est arrivé la norme IEEE 7xx...et des brouette qui permetait d'établir une norme de codage pour que les processeurs soient tous optimisés pour le même calcul des flotants.

    à priori il existe une DLL appellé MBF2IEEE.DLL qui permétrait de décoder tout ce bordel, sans se prendre le choux avec les mantise, et les exposant qui m'ont toujours donné mal au crane (chaqun son truc). bon j'essaye ça pour voir si ça marche.

    Merci encore.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 23
    Par défaut
    re bonjour,

    Bon en fait je programme pas en C, mais en windev (no-comment), mais je suis venu dans ce forum, car je me doutait qu'il y aurait des personnes compétentes pour me répondre.

    en fait la DLL dont je parle est inexploitable. par contre je sait qu'elle utilise des fonctione appelées : fmsbintoieee() et fmsbintoieee() et j'ai lu quelque part que ces fonctions seraient contenues dans math.h

    sauriez-vous où je pourait trouver une DLL qui contienne ces fonctions?

    Thx.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 23
    Par défaut
    Bonjour,

    Bon j'ai trouvé le code source des fonctions que le cherchais. je l'ai retranscrite en Windev, et ça marche au poil. pour ceux que ça interresse :

    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
     
    int _fmsbintoieee(float *src4, float *dest4)
    {
    unsigned char *msbin = (unsigned char *)src4;
    unsigned char *ieee = (unsigned char *)dest4;
    unsigned char sign = 0x00;
    unsigned char ieee_exp = 0x00;
    int i;
    /* MS Binary Format */
    /* byte order => m3 | m2 | m1 | exponent */
    /* m1 is most significant byte => sbbb|bbbb */
    /* m3 is the least significant byte */
    /* m = mantissa byte */
    /* s = sign bit */
    /* b = bit */
    sign = msbin[2] & 0x80; /* 1000|0000b */
    /* IEEE Single Precision Float Format */
    /* m3 m2 m1 exponent */
    /* mmmm|mmmm mmmm|mmmm emmm|mmmm seee|eeee */
    /* s = sign bit */
    /* e = exponent bit */
    /* m = mantissa bit */
    for (i=0; i<4; i++) ieee[i] = 0;
    /* any msbin w/ exponent of zero = zero */
    if (msbin[3] == 0) return 0;
    ieee[3] |= sign;
    /* MBF is bias 128 and IEEE is bias 127. ALSO, MBF places */
    /* the decimal point before the assumed bit, while */
    /* IEEE places the decimal point after the assumed bit. */
    ieee_exp = msbin[3] - 2; /* actually, msbin[3]-1-128+127 */
    /* the first 7 bits of the exponent in ieee[3] */
    ieee[3] |= ieee_exp >> 1;
    /* the one remaining bit in first bin of ieee[2] */
    ieee[2] |= ieee_exp << 7;
    /* 0111|1111b : mask out the msbin sign bit */
    ieee[2] |= msbin[2] & 0x7f;
    ieee[1] = msbin[1];
    ieee[0] = msbin[0];
    return 0;
    }

  6. #6
    Invité de passage
    Inscrit en
    Octobre 2009
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 1
    Par défaut Conversion du code en c#
    Bonjour voici une conversion possible en C#


    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
    public static float SMDF(byte[] msbin)
            {
                byte[] ieee = new byte[4];
                byte sign = 0x00;
                byte ieee_exp = 0x00;
                int i;
                /* MS Binary Format */
                /* byte order => m3 | m2 | m1 | exponent */
                /* m1 is most significant byte => sbbb|bbbb */
                /* m3 is the least significant byte */
                /* m = mantissa byte */
                /* s = sign bit */
                /* b = bit */
                sign = (byte)(msbin[2] & 0x80); /* 1000|0000b */
                /* IEEE Single Precision Float Format */
                /* m3 m2 m1 exponent */
                /* mmmm|mmmm mmmm|mmmm emmm|mmmm seee|eeee */
                /* s = sign bit */
                /* e = exponent bit */
                /* m = mantissa bit */
                for (i = 0; i < 4; i++) ieee[i] = 0;
                /* any msbin w/ exponent of zero = zero */
                if (msbin[3] == 0) return 0;
                ieee[3] |= sign;
                /* MBF is bias 128 and IEEE is bias 127. ALSO, MBF places */
                /* the decimal point before the assumed bit, while */
                /* IEEE places the decimal point after the assumed bit. */
                ieee_exp = (byte)(msbin[3] - 2); /* actually, msbin[3]-1-128+127 */
                /* the first 7 bits of the exponent in ieee[3] */
                ieee[3] |= (byte)(ieee_exp >> 1);
                /* the one remaining bit in first bin of ieee[2] */
                ieee[2] |= (byte)(ieee_exp << 7);
                /* 0111|1111b : mask out the msbin sign bit */
                ieee[2] |= (byte)(msbin[2] & 0x7f);
                ieee[1] = msbin[1];
                ieee[0] = msbin[0];
     
                IntPtr _IntPtr = Marshal.AllocHGlobal(4);
                sSingle value = new sSingle(0);
                Marshal.Copy(ieee, 0 , _IntPtr, 4);
                value = (sSingle)Marshal.PtrToStructure(_IntPtr, typeof(sSingle));
                return value.donnee;
            }
     
    private struct sDouble
            {
                public double donnee;
                public sDouble(double v)
                {
                    donnee = v;
                }
            }
    je recherche aussi algo pour les DMDF .

    merci

  7. #7
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    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 : 952
    Par défaut
    Citation Envoyé par netoale Voir le message
    Bonjour,

    je chèrche à récupérer des données d'un vieux logiciel écrit en GW Basic.
    ce sont des bases de données à accés aléatoire.
    j'arrive à récuperer les chaines, mais pas les réels.
    Je pense que le plus simple est d'écrire une moulinette en GW qui exporte les données au format texte, exemple "123.456". Il serait alors très facile de le récupérer en C ou tout langage qui a l'équivalent d'une fonction "chaine vers flottant". En plus tu t'affranchirais totalement des spécificités des formats des flottants à travers les âges.

    A+

    Pfeuh

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

Discussions similaires

  1. nombre réels -simple et double précision
    Par new_wave dans le forum Langage
    Réponses: 7
    Dernier message: 12/11/2009, 23h34
  2. Réponses: 4
    Dernier message: 15/06/2009, 06h02
  3. [Cookies] Guillemets simples et doubles?
    Par Yoyo_galère dans le forum Langage
    Réponses: 7
    Dernier message: 12/02/2005, 19h31
  4. Réponses: 4
    Dernier message: 05/07/2004, 13h17
  5. convertir un nom long (win32) en format dos (8+3)
    Par kylekiller dans le forum Langage
    Réponses: 2
    Dernier message: 30/08/2002, 13h34

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