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 :

pb test entier float


Sujet :

C

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 4
    Par défaut pb test entier float
    bonjour,

    voila je fais une boucle ou j'incremente des float (0.00001), et je voudrais stopper ma boucle a chaque fois que je tombe sur une valeur exacte
    ex : 1.0000

    comment je peux faire ?

    Merci

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Pour commencer, as-tu lu la FAQ sur la comparaison de float ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par toultemps
    voila je fais une boucle ou j'incremente des float (0.00001), et je voudrais stopper ma boucle a chaque fois que je tombe sur une valeur exacte
    ex : 1.0000
    'flottants' et 'valeurs exactes' sont des mots qui ne vont pas ensemble...
    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
     
    #include <stdio.h>
    #include <float.h>
     
    int main (void)
    {
       double n = 1;
     
       printf ("%.10f\n", n + (0 * DBL_EPSILON));
       printf ("%.10f\n", n + (1E0 * DBL_EPSILON));
       printf ("%.10f\n", n + (1E1 * DBL_EPSILON));
       printf ("%.10f\n", n + (1E2 * DBL_EPSILON));
       printf ("%.10f\n", n + (1E3 * DBL_EPSILON));
       printf ("%.10f\n", n + (1E4 * DBL_EPSILON));
       printf ("%.10f\n", n + (1E5 * DBL_EPSILON));
       printf ("%.10f\n", n + (1E6 * DBL_EPSILON));
       printf ("%.10f\n", n + (1E7 * DBL_EPSILON));
       printf ("%.10f\n", n + (1E8 * DBL_EPSILON));
       printf ("%.10f\n", n + (1E9 * DBL_EPSILON));
     
       return 0;
    }
    Chez moi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    1.0000000000
    1.0000000000
    1.0000000000
    1.0000000000
    1.0000000000
    1.0000000000
    1.0000000000
    1.0000000002
    1.0000000022
    1.0000000222
    1.0000002220
     
    Press ENTER to continue.
    On peut faire des comparaisons avec FLT_EPSILON (<float.h>. D'ailleurs je recommande double pour une meilleur précision (DBL_EPSILON)...

    Mais tout ça restera approximatif.

  4. #4
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Utilise plutôt des entiers pour la boucle, que tu convertis en float quand tu en a besoin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #define UNITE 10000 
    float f;
    for(int i = 0; i < MAX; ++i) {
        f = i / (float)UNITE;
        /* code */
        if (0 == i % UNITE) {
            /* ici f est un entier */
        }
    }

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Comme dit Emmanuel, il est toujours mieux de prendre des doubles pour les calculs en virgule flottante, ne serait-ce que par le fait que c'est le type naturel utilisé par C. Tout passage de paramètres float dans une fonction est automatiquement casté en double au passage, et re-casté en float à la sortie (ce qui d'ailleurs peut générer de graves problèmes).

    D'autre part, pour la vérification d'une précision d'un nombre en virgule flottante, le mieux est de vérifier comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if ( fabs(Valeur - Valeur_Reference) <= DBL_EPSILON )
      {
      }

  6. #6
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par souviron34
    Tout passage de paramètres float dans une fonction est automatiquement casté en double au passage, et re-casté en float à la sortie (ce qui d'ailleurs peut générer de graves problèmes).
    Si le paramètre/retour est de type double... ou que c'est une fonction variadic. Sinon, les paramètres explicites de type float existent. Il y a des fonctions 'f' déclarées dans <math.h> de C99.

    expf(), sqrtf() sinf() etc. On peu supposer que dans ce cas, les calculs sont fait en float...

  7. #7
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Il y a des fonctions 'f' déclarées dans <math.h> de C99.

    expf(), sqrtf() sinf() etc. On peu supposer que dans ce cas, les calculs sont fait en float...
    Oui bien sûr...

    Mais remarque je ne sais pas comment ça fonctionne en interne...

    Je sais par contre que, en dehors des fonctions de maths, pour des fonctions faites par toi, et dont les paramères sont float, (mais même ça a peut-être changé avec C99, je ne sais pas), mais le cast est fait automatiquement. Et passer des floats amène à très brève échance à des catastophes (du style variable de sortie n'ayant plus rien à voir avec la vraie valeur..)

    En gros (en tous cas pré-99), utiliser des floats est quasi suicidaire sur un programme assez gros..

  8. #8
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut Re:
    Citation Envoyé par toultemps
    je voudrais stopper ma boucle a chaque fois que je tombe sur une valeur exacte
    ex : 1.0000

    comment je peux faire ?
    C'est peut-être la fonction floor() que tu cherches? C'est la fonction Partie Entière. Exemple floor(9.81) retourne 9.000000. x est donc un "entier" si fabs( x - floor(x) ) < DBL_EPSILON. Les fonctions floor() et fabs() sont déclarées dans math.h

  9. #9
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Melem
    C'est peut-être la fonction ceil() que tu cherches? C'est la fonction Partie Entière. Exemple ceil(9.81) retourne 9.000000. x est donc un "entier" si fabs( x - ceil(x) ) < DBL_EPSILON. Les fonctions ceil() et fabs() sont déclarées dans math.h

    encore une fois tout faux......

    Comme son nom l'indique, ceil (plafond en français) donne le nombre entier SUPERIEUR....

    ceil(9.81) donne 10.0

    alors que floor (plancher en français) donne le nombre entier INFERIEUR

    floor(9.81) donne 9.0

  10. #10
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par souviron34
    Comme son nom l'indique, ceil (plafond en français) donne le nombre entier SUPERIEUR....

    ceil(9.81) donne 10.0

    alors que floor (plancher en français) donne le nombre entier INFERIEUR

    floor(9.81) donne 9.0
    Illustration :
    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
     
    #include <stdio.h>
    #include <math.h>
     
    int main (void)
    {
       double n = 1;
     
       while (n < 2.2)
       {
          printf ("%.2f %.2f %.2f \n", floor (n), n, ceil (n));
          n += .1;
       }
     
       return 0;
    }
    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
     
    1.00 1.00 1.00
    1.00 1.10 2.00
    1.00 1.20 2.00
    1.00 1.30 2.00
    1.00 1.40 2.00
    1.00 1.50 2.00
    1.00 1.60 2.00
    1.00 1.70 2.00
    1.00 1.80 2.00
    1.00 1.90 2.00
    2.00 2.00 3.00
    2.00 2.10 3.00
     
    Press ENTER to continue.

  11. #11
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    2.00 2.00 3.00
    Cette ligne est due aux imprécisions ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Médinoc
    Cette ligne est due aux imprécisions ?
    Oui :
    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
     
    1.00 1.0000000000000000 1.00
    1.00 1.1000000000000001 2.00
    1.00 1.2000000000000002 2.00
    1.00 1.3000000000000003 2.00
    1.00 1.4000000000000004 2.00
    1.00 1.5000000000000004 2.00
    1.00 1.6000000000000005 2.00
    1.00 1.7000000000000006 2.00
    1.00 1.8000000000000007 2.00
    1.00 1.9000000000000008 2.00
    2.00 2.0000000000000009 3.00
    2.00 2.1000000000000010 3.00
     
    Press ENTER to continue.

  13. #13
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Désolé pour le post erroné de tout à l'heure. La fonction partie entière c'est floor() bien sur, c'était juste une grosse faute d'innattention c'est tout

Discussions similaires

  1. Fonctions test entier et test carré
    Par piotrr dans le forum Général Python
    Réponses: 4
    Dernier message: 19/11/2007, 16h55
  2. test entier js
    Par franfr57 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 30/05/2007, 20h46
  3. pl/sql test si entier ou flottant
    Par moulery dans le forum PL/SQL
    Réponses: 5
    Dernier message: 09/03/2007, 10h51
  4. test comparatif de deux entiers
    Par sisiso dans le forum C
    Réponses: 12
    Dernier message: 26/01/2007, 22h37
  5. Test if sur des float
    Par Minuit dans le forum Linux
    Réponses: 2
    Dernier message: 26/03/2005, 13h08

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