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 :

condition pas respectée et atof :(


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut condition pas respectée et atof :(
    Bonjour tous,

    je viens vous soumettre un de mes problèmes, j'espère que vous pourrez me débloquer car là je ne sais plus trop quoi faire...

    je vous explique :

    j'ai un fichier texte qui contient des données : "0.1 45.458 0.2 452.5 ...Etc"
    je viens lire ces données ligne par ligne et je stock chacun de ces nombres dans un vecteur de string "vector<string> myNb"

    ensuite je viens faire un conversion de ces composantes de "string" vers "double" avec la commande "atof".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mesDoubles.push_back((atof(myNb[i].c_str())));
    ensuite dans mon code je viens faire un test sur ces nombres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(45.458==mesDoubles[i])
    mon soucis :

    tout ceci fonctionne parfaitement excepté lors du test "if"
    même si dans mon fichier texte j'ai le nombre "45.458" il ne sera transformé par atof en "45.457999999999999999999999"
    et du coup ma condition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(45.458==mesDoubles[i])
    qui devrait être vrai ne l'ai jamais...

    Question :

    du coup, je voudrais savoir comment dois je faire pour que ce test soit vrai lorsque 45.458 est enregistré dans le code en
    temps que "45.457999999999999999999999" ??

    est il possible que "atof" m'enregistre automatiquement la valeur exacte "45.458" ???

    je vous remercie pour l'aide que vous pourrez m'apportez !!!

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    double & float. tout est dit.

    Les nombres flottants ne sont pas une suite de digits après une virgule, mais une suite de bits après une virgule (et avec uniquement 1 avant la virgule), multipliée par une puissance de 2 (ou 10, je n'arrive pas à le retenir).

    Il s'agit d'une somme limitée de puissance négative de 2:

    1 = 1/1 + 0/2 + 0/4 + 0/8 …
    1,5 = 1/1 + 1/2
    45.457999999999999999999999 = des choses...
    45.458 n'est pas possible avec cette écriture.
    renseigne toi sur l'erreur flottante.

    En tout état de cause, l'égalité est impossible entre nombres flottants.

    suppose les fichiers suivants:
    Code autre.h : Sélectionner tout - Visualiser dans une fenêtre à part
    double unite();
    Code autre.c : Sélectionner tout - Visualiser dans une fenêtre à part
    double unite(){return 1.0;}
    Code main.c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "autre.h"
    #include <iostream>
    int main(){
        std::cout << ( ( (unite()+0.1)==1.1 ) ? "vrai" : "faux" ) <<std::endl;
    }

    Une fois compilés, on obtient "faux", parce que 1.1 = 1 + 1/16 + 1/32 + 1/256 + 1/512 + ...

  3. #3
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 264
    Par défaut
    Bonjour,

    du coup, je voudrais savoir comment dois je faire pour que ce test soit vrai lorsque 45.458 est enregistré dans le code en
    temps que "45.457999999999999999999999" ??
    Tu peux faire la différence entre ta valeur à tester et ta variable et vérifier qu'elle est inférieure à une marge d'erreur (nommée ici EPSILON).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    double temp = (45.458 - mesDoubles[i]);
    if (abs(temp) < EPSILON)
    {
        // Code...
    }
    La valeur que tu choisiras pour EPSILON dépendra de tes besoins en précision.

    est il possible que "atof" m'enregistre automatiquement la valeur exacte "45.458" ???
    Non, comme l'a très bien expliqué Leternel, les unités de calculs à virgule flottante ne comptent pas en décimal, mais en binaire et ne peuvent représenter exactement le nombre 45,458.

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut
    Citation Envoyé par Niark13 Voir le message
    Tu peux faire la différence entre ta valeur à tester et ta variable et vérifier qu'elle est inférieure à une marge d'erreur (nommée ici EPSILON).
    OK merci. Je vois ce que tu veux dire

    => par contre est il possible de définir EPSILON egale à l'incertitude de mes variables facilement ?

    => pour des doubles c'est 1e-15 la précision ? je peux donc mettre EPSILON=1e-14 ?

  5. #5
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    tu as un numeric_limits<double>::epsilon(), je crois.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut
    merci l'éternel ! c'est exactement ce que je cherchais !

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut
    merci de ta réponse leternel mais je n'ai pas tout saisi.... que veux tu dire par pas de test possible sur des flottants ? et sur la différence flottant / double ?

    Precision = voici les étapes de ce bout de code :
    ------------------------------------------------------------
    1°) je lis dans un fichier une base de donnée rentrée par un utilisateur,
    j'enregistre ceci dans des string puis des double (avec atof) et j'ai ma base de donnée de référence.
    2°) je fais des conversions d'unités de ma base de donnée (toujours en double)
    3°) je test si ces nombres qui appartiennent à la base de donnée sont bien égaux au résultat d'un calcul enregistré dans un autre fichier texte.
    ==> je n'ai pas le choix j'ai forcement quelque chose qui peut être différent d'un entier
    ==> comment savoir si un nombre de ma base de donnée existe dans un fichier si je ne peux pas le tester ?

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

Discussions similaires

  1. [AC-2003] Boucle DO, incrementation si condition pas respectée
    Par jubourbon dans le forum VBA Access
    Réponses: 3
    Dernier message: 17/10/2011, 17h32
  2. Erreur de condition (pas logique)
    Par Khleo dans le forum Langage
    Réponses: 6
    Dernier message: 04/08/2008, 00h43
  3. [MySQL] Les conditions de ma requête ne sont pas respectées
    Par babou54 dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 13/02/2008, 12h28
  4. Le padding n'est pas respecter lors d'un retour a la ligne
    Par pierrot10 dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 07/03/2007, 14h50
  5. Réponses: 2
    Dernier message: 06/04/2006, 09h17

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