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 :

Question sur les flottants


Sujet :

C

  1. #1
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut Question sur les flottants
    Salux,

    Un truc me tracasse depuis longtemps, on sait qu'un flottant n'a pas de valeur absolument determinée et si j'ai bien compris, 3.0 peut valoir en realité 2.99999 ou 3.000001.
    C'est qd meme important de savoir si c'est 2.9999 ou 3.0001 lorsqu'on transtype en entier car dans un cas ça donne 2 et dans l'autre ça donne 3.

    Ma question est : est-ce qu'on peut assumer que les fonctions ceil et floor renvoient un flottant forcement legerement supérieur à la valeur entière resultat? est ce que ceil(2.1) vaut toujours 3.00000000001 ?

    Mercix

  2. #2
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Gruik
    Un truc me tracasse depuis longtemps, on sait qu'un flottant n'a pas de valeur absolument determinée
    Si.

    et si j'ai bien compris, 3.0 peut valoir en realité 2.99999 ou 3.000001.
    Les entiers sont exactement representables dans tous les formats de flottants que je connais. Autrement dit 3.0 sera toujours 3.0.

  3. #3
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    En fait, ya plus ou moins le meme probleme avec le paramètre de ceil et floor.. est-ce que ceil(6.0 / 2.0) va evaluer ceil(3.0001) ou ceil (2.9999)?

  4. #4
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Si.



    Les entiers sont exactement representables dans tous les formats de flottants que je connais. Autrement dit 3.0 sera toujours 3.0.
    Mais 3.0 ne sera jamais 3, c'est ça?

  5. #5
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Gruik
    En fait, ya plus ou moins le meme probleme avec le paramètre de ceil et floor.. est-ce que ceil(6.0 / 2.0) va evaluer ceil(3.0001) ou ceil (2.9999)?
    6 et 2 sont des entiers, donc representables exactement. Leur quotient est un entier, donc representable exactement. Les implementations actuelles des flottants donne le resultat exact quand il est representable, on a donc ceil(3.0000).

    Si tu poses la question avec ceil(6.6/2.2), ca va dependre car ni 6.6 ni 2.2 sont representables exactement.

  6. #6
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Il me semblait que 0 n'était pas "representable exactement", je pensais que c'était pareil pour tous les entiers

  7. #7
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Gruik
    Il me semblait que 0 n'était pas "representable exactement", je pensais que c'était pareil pour tous les entiers
    0.0 est representable exactement. Mais il a deux representations: +0.0 et -0.0 ce qui fait quelques surprises. Par exemple 0.0-x pour x = 0.0 vaut +0.0, -x pour x = 0.0 vaut -0.0. Mais +0.0 == -0.0 donc la difference ne s'observe que difficilement.

  8. #8
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    D'accord

    Du coup, on peut tester "x == 3" si x vaut 3.0 ?

  9. #9
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Un test x == y va tester si les representations sont egales.

    Il y a deux moments qui peuvent introduire une difference entre la valeur representee et la valeur ideale: lors de l'entree des donnees, peu de valeurs ecrites en decimal sont representables exactement, mais les entiers en font partie tant qu'ils ne sont pas trop grand.

    Lors de calculs, le resultat ideal peut ne pas etre representable non plus.

    Par exemple 1.9 * 3.1, premiere source d'erreur 1.9 sera represente par 1.9+e1 (avec e1 petit, potentiellement negatif) et 3.1 par 3.1+e2. Deuxieme source d'erreur, la valeur
    (1.9+e1)*(3.1+e2) n'est vraissemblablement pas representable exactement non plus, donc le resultat sera (1.9+e1)*(3.1+e2)+e3. Le resultat parfait (5.89) n'est pas non plus representable exactement, il sera arrondi a 5.89+e4 qui a toute les chances d'etre different de (1.9+e1)*(3.1+e2)+e3.

    Complication supplementaire, en C le compilateur peut decider de faire les calculs avec une plus grande precision que celle des variables. Donc x = 1.9; y = 3.1; x*y peut etre different de 1.9*3.1.

    Et cerise sur le gateau, quand certains compilateurs (gcc en tete) gardent cette precision supplementaire meme quand il y a un cast ou assignation a une variable.

  10. #10
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Hmm merci pour ces eclaircissements

    Complication supplementaire, en C le compilateur peut decider de faire les calculs avec une plus grande precision que celle des variables. Donc x = 1.9; y = 3.1; x*y peut etre different de 1.9*3.1.
    Oui dans le cas de 1.9*3.1 ça serait le preprocesseur qui fait les calculs

  11. #11
    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 Gruik
    D'accord

    Du coup, on peut tester "x == 3" si x vaut 3.0 ?
    non, pas si x est un double/float.

    La manière absolue de faire est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if ( fabs(x-3.0) < DBL_EPSILON )
    Par contre, oui les fonctions floor et ceil devraient fonctionner quel que soit le cas... Le fait d'avoir des 1 ou autres choses à partir d'une certaine précision est systématique (c'est dans le codage interne). "Normalement", dans les implémentations que j'ai vues en tous cas, les fonctions en tiennent compte.

  12. #12
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Citation Envoyé par souviron34
    non, pas si x est un double/float.

    La manière absolue de faire est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if ( fabs(x-3.0) < DBL_EPSILON )
    Mais si on suit l'explication de JMB, 3.0 vaut vraiement 3.0 et ceci serait correct
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    double x = 3.0, y = 3.0;
    assert(x == y);
    assert(x == 3.0);
    De meme que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    assert(x * 2.0 == 6.0);
    assert(9.0 / y == x);
    Et par conséquent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    assert((int)x == 3);
    assert((int)(9.0 / y) == (int)x);

  13. #13
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Gruik
    Oui dans le cas de 1.9*3.1 ça serait le preprocesseur qui fait les calculs
    Certainement pas. Le compilateur peut eventuellement le faire a la compilation, mais le preprocesseur pas. Les seuls calculs faits par le preprocesseur sont dans les lignes #if/#elif et sont des calculs entiers.

  14. #14
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par souviron34
    La manière absolue de faire est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if ( fabs(x-3.0) < DBL_EPSILON )
    Ca, c'est certainement pas la maniere a faire. Pour commencer, elle est equivalente a x == 3 sauf quand le bug de gcc intervient. Voir les archives pour une explication.

  15. #15
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Ca, c'est certainement pas la maniere a faire. Pour commencer, elle est equivalente a x == 3...
    Pourriez-vous être plus précis?

  16. #16
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Gruik
    Mais si on suit l'explication de JMB, 3.0 vaut vraiement 3.0 et ceci serait correct
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    double x = 3.0, y = 3.0;
    assert(x == y);
    assert(x == 3.0);
    De meme que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    assert(x * 2.0 == 6.0);
    assert(9.0 / y == x);
    Et par conséquent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    assert((int)x == 3);
    assert((int)(9.0 / y) == (int)x);
    Oui. Mais attention
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    double x= 4.4, y = 2.2;
    ne permet pas de conclure que x == 2*y car 4.4 et 2.2 ne sont pas exactement representable.

  17. #17
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par stephl
    Pourriez-vous être plus précis?
    C'est quoi la definition de DBL_EPSILON?

  18. #18
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Certainement pas. Le compilateur peut eventuellement le faire a la compilation, mais le preprocesseur pas. Les seuls calculs faits par le preprocesseur sont dans les lignes #if/#elif et sont des calculs entiers.
    Oui, c'est le compilateur qui le fait, je me suis embrouillé

  19. #19
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    C'est quoi la definition de DBL_EPSILON?
    C'est une tolérance à définir.

  20. #20
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    C'est quoi la definition de DBL_EPSILON?
    Chcrois bien que c'est la plus petite valeur d'un double et donc la plus petite difference de valeur qu'il peut yavoir entre 2 doubles.. normalement les e1, e2, e3 dans ton exemple devraient etre inferieurs à cette constante

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. Petite question sur les performances de Postgres ...
    Par cb44 dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 13/01/2004, 13h49
  2. question sur les vertex buffer et index buffer
    Par airseb dans le forum DirectX
    Réponses: 9
    Dernier message: 25/08/2003, 02h38
  3. question sur les variables globales et les thread posix
    Par souris_sonic dans le forum POSIX
    Réponses: 5
    Dernier message: 13/06/2003, 13h59
  4. Question sur les handles et les couleurs...
    Par MrDuChnok dans le forum C++Builder
    Réponses: 7
    Dernier message: 29/10/2002, 08h45
  5. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11

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