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

Delphi Discussion :

[Delphi 6] probleme de precision avec StrToFloat()


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2005
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 33
    Par défaut [Delphi 6] probleme de precision avec StrToFloat()
    Bonjour,

    j ai un probleme de conversion avec la fonction StrToFloat() sous Delphi 6. Peut-etre quelqu un aura-t-il une solution simple a proposer.

    J'ai une valeur numérique qui est saisie dans une StringGrid (par exemple, 0.001).
    Je souhaite la convertir en Double pour pouvoir la traiter comme une valeur numérique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    stepValue : Double;
    stepValue := StrToFloat(grid.Cells[3,1]);
    avec grid.Cells[3,1], la cellule contenant la valeur numerique.

    Le probleme est que stepValue ne va pas valoir "0.001" mais "0.001 plus ou moins un epsilon" (0.00999999999). Cette erreur de precision a des répercussion dramatique sur le reste de mon programme.

    Par exemple, si je fais floor(1/stepValue), resultat ne vaut pas 1000 mais 999

    Je pense que le probleme peut provenir du fait que StrToFloat fournit un 'extented' alors que ma variable est de type 'double'.

    Comment puis-je regler mon probleme de conversion 'string' -> 'double' si vous plait ? Comment eviter une perte de precision lors du passage 'string' vers 'double' ?

    Ludo

  2. #2
    Membre éprouvé
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Par défaut
    Le problème des flottants est toujours omniprésent, et ne stocke pas forcément la réalité du nombre visuel (qui est ou non un arrondi).

    Dans ce cas, utilise un extended et non pas un double, qui permet d'avoir une plus grande précision, mais le problème des arrondis subistera sur certaines valeurs (on tombe ou non dessus...)

    Si tu veux être absolument certains des valeurs, et si tes nombres sont dans une fourchette raisonnable, tu peux avoir 2 solutions:
    Utiliser des Currency (la virgule est fixe, ce ne sont pas des flottants),
    ou alors des entiers que tu multiplies/divisent par un certains coef selon la précision souhaitée.

    Ceci dit, avec ton exemple 0.001, double ou extended donnent strictement le bon résultat en essayant FloatToStr.
    J'ai testé ce 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
    procedure TForm1.Button1Click(Sender: TObject);
    var
       d: double;
    begin
         d := StrToFloat( Edit1.Text );
         Label1.caption := FloatToStr( d );
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
       e: extended;
    begin
         e := StrToFloat( Edit1.Text );
         Label2.caption := FloatToStr( e );
    end;
    as tu un nombre particulier qui pose problème ?
    Section Delphi
    La mine d'or: La FAQ, les Sources

    Un développement compliqué paraitra simple pour l'utilisateur, frustrant non ?
    Notre revanche ? l'inverse est aussi vrai ;-)

  3. #3
    Membre chevronné
    Avatar de Philippe Gormand
    Inscrit en
    Mars 2002
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 330
    Par défaut
    Bonjour.

    Tu peux utiliser la procédure "Val" qui (à ma connaissance) n'a pas le problème de la fonction "StrToFloat".

    A+

  4. #4
    Membre averti
    Inscrit en
    Mars 2005
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 33
    Par défaut
    Salut,

    Merci pour les réponses

    @Phil
    La fonction 'val' ne corrige malheureusement pas le probleme.

    @TicTacToe
    Ton bout de code marche, mais comme tu le disais, ce qui est affiché n'est pas forcement la valeur réel. Comme dans mon cas, lorsque j affiche mes variables, aucun probleme en apparence.
    Tu peux essayer Floor(1/d) avec 0.001. J obtiens 999 au lieu de 1000. C est tres tres genant dans mon cas car mon algo fait 999 iterations au lieu des 1000 prevues

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 488
    Par défaut
    Citation Envoyé par ludovic tambour
    Tu peux essayer Floor(1/d) avec 0.001. J obtiens 999 au lieu de 1000. C est tres tres genant dans mon cas car mon algo fait 999 iterations au lieu des 1000 prevues
    Tu peux utiliser Round(1/d) qui lui donnera 1000. Je ne sais pas si ça répond à ton problème.

  6. #6
    Membre averti
    Inscrit en
    Mars 2005
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 33
    Par défaut
    @TicTaeToe

    Le probleme est visible en inserant dans ton code : d := Floor(1/d);

    idem avec les extended.

    Si tu saisie 0.001, tu as un probleme avec des double, mais aucun probleme avec des extended.

    Je vais etre obligé de passer mes variables en Extended. A vrai dire, cette solution me convient a moitié. D apres doc sur Delphi, le type Extended est moins portable que le type Double. C est pour cela que je preferai rester en double.

    Ludo

  7. #7
    Membre averti
    Inscrit en
    Mars 2005
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 33
    Par défaut
    @sovitec

    L'utilisation de 'round' n ira pas dans mon probleme

    A vrai dire, j ai 2 choses a faire où ce probleme de précision pose problème.

    1) Le premier problème est de faire évoluer une variable 'currentValue' depuis 'minValue' jusqu'à 'maxValue' avec un pas de 'stepValue'. 'minValue', 'maxValue' et 'stepValue' sont saisies initialement comme des String puis convertit en double via StrToFloat. Si minValue = '499', maxValue = '500' et stepValue = '0.001', du fait du probleme de precision, 'stepValue' peut etre interprété comme valant '0.001000...001'. Donc, a la derniere iteration, currentValue ne vaudra pas 500 mais 499

    2) Determiné le nombre d'iteration qui sera realisé pas (1). La formule est : floor((maxValue-minValue)/stepValue) + 1;

    Comme expliqué precedement, j aurais un probleme si '0.001' est interprété comme valant '0.009999999....'

    Encore merci pour vos reponse

    ludo

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 488
    Par défaut
    Citation Envoyé par Philippe Gormand
    Tu peux utiliser la procédure "Val" qui (à ma connaissance) n'a pas le problème de la fonction "StrToFloat".
    Non, non, comme l'a dit TicTacToe le problème est plus profond : Il n'existe pas de représentation exacte de 0.001 en double, aucune fonction de conversion ne pourra rien y faire. Par contre beaucoup de composants permettent de limiter le nombre de chiffres après la virgule qui sont affichés.

Discussions similaires

  1. Probleme d'enregistrement avec delphi
    Par scofield1 dans le forum Bases de données
    Réponses: 5
    Dernier message: 12/09/2011, 18h38
  2. [Delphi 4] Probleme sur Blob null avec UpdateSQL
    Par Invité dans le forum Bases de données
    Réponses: 4
    Dernier message: 25/05/2010, 21h15
  3. probleme d'affichage avec delphi 2009
    Par dz_bill dans le forum EDI
    Réponses: 1
    Dernier message: 19/08/2009, 11h49
  4. [Delphi] [DLL] Problème avec un paramètre PChar
    Par Mickey.jet dans le forum Langage
    Réponses: 1
    Dernier message: 22/03/2006, 16h43
  5. probleme avec strtofloat
    Par copeau31 dans le forum Langage
    Réponses: 6
    Dernier message: 20/01/2006, 19h24

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