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

Langage Delphi Discussion :

[D2006] Lecture d'un réel et conversion en chaîne


Sujet :

Langage Delphi

  1. #1
    Membre averti

    Homme Profil pro
    ingénieur, retraité
    Inscrit en
    Février 2007
    Messages
    230
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : ingénieur, retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 230
    Points : 332
    Points
    332
    Par défaut [D2006] Lecture d'un réel et conversion en chaîne
    Bonjour,

    Dans une procédure qui lit les octets d'un fichier j'extrait 8 octets successifs
    représentant un réel double, dont je veux obtenir la valeur numérique avec le code suivant :

    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
    type
      TypArray64 =  array[0..63] of byte;  // rectifié
      TabToN8 = record
        case integer  of
        1 : (Val : double; Suit : array[1..56] of byte);
        2 : (Tab : TypArray64);
      end;
      ...
    var
      BUFF : array[1..128] of byte;
      ...
      Lig : string;
      ChChamp : string;  // chaîne du champ pour affichage
      ValCh : Double;    // valeur d'un champ numérique
      Champ : TypArray64; 
      Lchamp : TabToN8;
      K, L :byte;
      Lg, Debut, Fin : integer;       // longueur du champ 
       ...    
    begin
      ...
      L := 0;           // corrigé
      Lg := TbLgChamp[J];    // longueur du champ
      Fin := Debut + Lg -1;    // fin du champ
      for K := Debut to Fin do    // lecture du contenu d'un champ
      begin
        Champ[L] := Buff[K];
        inc(L)
      end;
      Champ[TbLgChamp[J]] := byte(#0);    // fermeture du champ  Corrigé
      ...
     // traitement d'un champ numérique sans conversion, stocké comme un double
       ...
       LChamp.Tab := Champ;      // affectation de champ lu au TypArray64
       ValCh :=  double(LChamp.Val);    // valeur numérique
       ChChamp := FloatToStr(ValCh);    // résultat PAS correct ????
       Lig := Lig + ChChamp + ' ';
       ...
    end;
    Le valeur brute du champ obtenu est correcte, mais le valeur numérique ChChamp est fausse.

    Y à t'il une solution à ce problème de conversion ?

    Merci pour vos réponses.

    PL

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 534
    Points : 25 082
    Points
    25 082
    Par défaut
    Que veux dire "Fausse" ? Valeur qui n'a rien à voir, erreur d'arrondi ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    essaie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ValCh := Double(@LChamp.Val)
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ValCh := PDouble(@LChamp.Val)^
    ou supprime le cast

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 534
    Points : 25 082
    Points
    25 082
    Par défaut
    Montor ? où as-tu vu une histoire de pointeur ?

    Sinon, ceci suffit !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ValCh :=  LChamp.Val;    // valeur numérique
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Montor ? où as-tu vu une histoire de pointeur ?

    Sinon, ceci suffit !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ValCh :=  LChamp.Val;    // valeur numérique
    c'est un transtypage des données bruts ex: voir la fonction(Math signe)
    tu peux dire cela a paulfr
    Citation Envoyé par Montor
    ou supprime le cast

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 534
    Points : 25 082
    Points
    25 082
    Par défaut
    Citation Envoyé par Montor Voir le message
    c'est un transtypage des données bruts ex: voir la fonction(Math signe)
    De données brutes ? Val est un Double, il est déjà typé par la structure variable ... je ne vois pas ce qu'un transtypage de double en double changera ..., pour la fonction Sign, c'est converti en un Entier sur 8 octets pour tromper le compilateur, car à tous les coups (j'ai pas vérifié), il refuse le transtypage Double -> Int64 directement (un petit erreur genre type incompatible), faut passer par un pointeur et déférencement ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre averti

    Homme Profil pro
    ingénieur, retraité
    Inscrit en
    Février 2007
    Messages
    230
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : ingénieur, retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 230
    Points : 332
    Points
    332
    Par défaut
    Réponse à Shail

    Les résultats obtenus sont totalement erronés, sauf pour les valeurs nulles,
    du type 1....E272 pour une valeur de 283.

    Merci pour votre intêret.

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 534
    Points : 25 082
    Points
    25 082
    Par défaut
    Quelle est la source de données ?
    Tu disais que la valeur brute du champ obtenu est correcte, selon quel critère ?
    Qui fourni la bonne valeur ? le débogueur ?
    es-tu sur si la source en BigEndian ou LittleEndian ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Membre averti

    Homme Profil pro
    ingénieur, retraité
    Inscrit en
    Février 2007
    Messages
    230
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : ingénieur, retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 230
    Points : 332
    Points
    332
    Par défaut
    La source est un fichier dBase crée avec une application Delphi 2006.
    Le fichier dBase est de niveau 7 (Visual dBase d'après internet).
    A ce niveau existe des champs de type numérique 'O' double, 8 bits, sans conversion, stocké comme un double.
    L'appli cherche à lire et afficher un fichier dBase sans utiliser "dBase" ( un wiever).
    Jusqu'au niveau 5 (dbase IV plus ...) c'est sans problème les numériques sont du type 'N' en caractères.

    Sous D2006 et Vista une type 'N' se retrouve en 'O' ( sous XP ce n'était le cas) ?

    Bigendian ou little indian connais pas (je suis un amateur étant passé de dBase à D3 compilé à titre personnel).

  10. #10
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 534
    Points : 25 082
    Points
    25 082
    Par défaut
    8 Bytes, et non 8 bits ...
    DBase, je crois que l'on utile encore du IV au bureau ...

    Donc, essaye d'inverser les octets, c'est à dire, si cela ne fonctionne pas vérifier que ce type O, est bien en IEEE 754

    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
    type
      TypArray64 =  array[0..63] of byte;  // rectifié
      TabToN8 = record
        case integer  of
        1 : (Val : Double; Suit : array[1..56] of byte);
        1 : (A : Array[0..7] of Byte; Dummy : array[1..56] of byte);
        2 : (Tab : TypArray64);
      end;
     
    ...  
     
      LChamp.Tab := Champ;      // affectation de champ lu au TypArray64
      for K := 0 to 3 do
      begin
        L  := A[7-K];
        A[7-K] := A[K];
        A[K] := L;
      end;
     
      ValCh :=  LChamp.Val;    // valeur numérique
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  11. #11
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    La fonction FloatToStr n'a aucun défaut je viens de tester sous D2006 c'est absurde l' erreur vient d'ailleur tu es sur que la valeur de ValCh est correct
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var
       s:TypArray64;
       v: TabToN8 ;
    begin
      PDouble(@s)^:=1234567890.123;
      v.Tab:=s;
     
      ShowMessage(FloatToStr(v.Val));
          //1234567890.123;
    Mais tu peux ajouter le mot Packed pour secutité

  12. #12
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 534
    Points : 25 082
    Points
    25 082
    Par défaut
    Citation Envoyé par Montor Voir le message
    ... c'est absurde...
    Qu'est ce qui est absurde ?
    On a jamais mis en doute la fiabilité de FloatToStr, mais l'encodage du champ dans TypArray64, typiquement l'ordre de stockage dans le fichier, Big ou Little Indian ... ou carrement un type autre que IEEE 754, un type maison, genre BCD !

    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
    procedure TFrmTestMemory.BtnSwapDoubleClick(Sender: TObject);
     
       function SwapDouble(Value: Double): Double;
       type
          TMapDouble = array[0..7] of Byte;
       var
         I: Integer;
       begin
          for I := 0 to 7 do
            TMapDouble(Result)[I] := TMapDouble(Value)[7 - I];
       end;
     
    var
      D, SD: Double;
    begin
    var
      D, SD, SSD: Double;
    begin
      D := 283;
      SD := SwapDouble(D);
      SSD := SwapDouble(SD);
      ShowMessage(FloatToStr(D)); // 283
      ShowMessage(FloatToStr(SD)); // 5,71304311639417E-317
      ShowMessage(FloatToStr(SSD)); // 283
    end;
    c'est très ressemblant à son problème non ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  13. #13
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    Qu'est ce qui est absurde ?
    au debut il disait que la valeur brute est correct
    désoler j'etait stupide avec (fvExtended,fvCurrency) moi aussi j'essaie d'apprendre
    oui c'est semblable mais c'est a lui de confirmer

  14. #14
    Membre averti

    Homme Profil pro
    ingénieur, retraité
    Inscrit en
    Février 2007
    Messages
    230
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : ingénieur, retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 230
    Points : 332
    Points
    332
    Par défaut
    Je viens de compléter le programme suivant les indications de ShaiLeTroll.
    Le résultat est là.
    ci-joint ce que j'obtiens.

    Merci pour votre solution et votre aide
    PL

  15. #15
    Membre averti

    Homme Profil pro
    ingénieur, retraité
    Inscrit en
    Février 2007
    Messages
    230
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : ingénieur, retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 230
    Points : 332
    Points
    332
    Par défaut
    Ma vérification a été un peu rapide (vu l'heure).
    Les nombres positifs sont corrects au signe prés ?
    Mais les nombres négatifs sont transformés en une valeur nulle, ou presque
    exemple : -413.44 donne 0.01
    -1973.00 ---> 0.00
    -2875.59 ---> 0.00 ...
    Le problème n'est donc pas totalement résolu.
    A t'il une solution ?
    J'ai annulé "Résolu".

    Merci à tous.

Discussions similaires

  1. Réponses: 4
    Dernier message: 05/02/2014, 11h01
  2. Réponses: 35
    Dernier message: 07/05/2013, 11h57
  3. Réponses: 6
    Dernier message: 01/10/2012, 23h33
  4. Lecture en temps réel et affichage
    Par Koko33 dans le forum Qt
    Réponses: 2
    Dernier message: 15/03/2012, 13h46
  5. lecture en temp réel sur spectre
    Par diaso dans le forum C++
    Réponses: 0
    Dernier message: 02/09/2009, 17h54

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