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

Python Discussion :

[Python 2.7] Problème comparaison entre float


Sujet :

Python

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 3
    Par défaut [Python 2.7] Problème comparaison entre float
    Bonjour,
    Quelqu'un a-t-il déjà rencontré un problème de resultat de comparaison erroné entre deux float ?
    Ma fille qui est en mpsi a eu un petit pb de math à résoudre en python (calcul d'integrale sur un intervale par approximation de calcul d'aire de recrangles).
    Un énoncé bien grand pour un programme qui se limite a faire une simple boucle qui ajoute une aire de rectangle à la somme des aires precedemment calculée.
    Donc, elle a ecrit une petit fonction qui a comme arguments le point de depart de l'aire à calculer (a), le point de fin de l'aire à calculer (b) et le nombre de rectangles à utiliser (n) (a l'origine il y avait aussi en argument la fonction à integrer).
    On calcule la largeur des rectangles en fonction du nombre de rectangles voulus "pas=(b-a)/n"
    Et on fait une boucle avec un x qui demarre à "a". On calcule notre aire de rectangle. Et on deplace "x" de "pas" à chaque tour tant que x est strictement inferieur à "b".
    Beton dirait-on !
    ET bien non... On se retrouve dans certains cas avec un tour de boucle en trop !!
    J'ai épuré completement le programme en ne laissant que la boucle et en faisant quelques print a l'interieur pour voir ce qui se passe.
    J'ai donc un while x < b, voire un while 1 et un if x < b break et on se retrouve parfois quand même dans la boucle malgré un affichage par exemple x=8.0 et b=8.0, donc x egal b !!
    Il s'agit surement d'un pb du au codage des floats mais si quelqu'un a une explication plus académique, nous sommes preneurs.
    Je mets ci dessous le code ultra simplifié.
    J'y appelle 4 fois la fonction. 2 fois pour 5 rectangles et 2 fois pour 6.
    Dans le cas de 5 avec 5 et 8 commes bornes, on fait un tour de trop, et c'est bon pour 0 à 0,5 comme bornes.
    Dans le cas de 6 avec 5 et 8 commes bornes, c'est bon, et pour 0 à 0,5 comme bornes on fait un tour de trop.
    SI on passe à 10, on fait sytématiquement un tour de trop....


    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    def f(a,b,n):
    x=a                 
        pas=(b-a)/n    
    #    while  x < b :    # même effet...
        while 1:
            if x < b :
                 print "x="+str(x)+"    b="+str(b)
                 x += pas
            else :
                 break      
     
    f(5.0,8.0,5)
    print
    f(0.0,0.5,5)
    print
    f(5.0,8.0,6)
    print
    f(0.0,0.5,6) 
     
     
    Resultat :
    x=5.0    b=8.0
    x=5.6    b=8.0
    x=6.2    b=8.0
    x=6.8    b=8.0
    x=7.4    b=8.0
    x=8.0    b=8.0  La il y a un tour de trop
     
    x=0.0    b=0.5
    x=0.1    b=0.5
    x=0.2    b=0.5
    x=0.3    b=0.5
    x=0.4    b=0.5
     
    x=5.0    b=8.0
    x=5.5    b=8.0
    x=6.0    b=8.0
    x=6.5    b=8.0
    x=7.0    b=8.0
    x=7.5    b=8.0
     
    x=0.0    b=0.5
    x=0.0833333333333    b=0.5
    x=0.166666666667    b=0.5
    x=0.25    b=0.5
    x=0.333333333333    b=0.5
    x=0.416666666667    b=0.5
    x=0.5    b=0.5                       La il y a un tour de trop aussi

    J'y perds mon ASCII !!!

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 304
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 304
    Par défaut
    Salut,

    Comme ceci ce n'est pas plus simple ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    def f(a, b, n):
        pas = (b - a) / n
        for i in range(n):
            print "x = %s b = %s" %(a, b)
            a += pas

  3. #3
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 681
    Par défaut
    Citation Envoyé par pipodug Voir le message
    Il s'agit surement d'un pb du au codage des floats mais si quelqu'un a une explication plus académique, nous sommes preneurs.
    C'est du au codage des floats et les explications plus académiques se trouvent sur le Web.
    Une conséquence surprenante est qu'ajouter le pas n fois est différent d'ajouter n*pas:
    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
    >>> a = 5.0; b = 8.0; n = 5
    >>> x = a
    >>> pas = (b - a)/n
    >>> for _ in range(6):
    ...     x += pas
    ...     print x, x < b, b - x
    ...
    5.6 True 2.4
    6.2 True 1.8
    6.8 True 1.2
    7.4 True 0.6
    8.0 True 1.7763568394e-15
    8.6 False -0.6
    >>> z = a + 5*pas
    >>> b == z
    True
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 3
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    C'est du au codage des floats et les explications plus académiques se trouvent sur le Web.

    - W
    Oui bien sur. Mais j'ai testé la même chose en C, pas de problème.
    Je trouve ça un peu gros. Surtout pour des valeurs "rondes" comme 0.8 ou 0.5.
    Donc, en python, bannir les comparaison de flotttants..
    Merci.

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 3
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    C'est du au codage des floats et les explications plus académiques se trouvent sur le Web.
    Une conséquence surprenante est qu'ajouter le pas n fois est différent d'ajouter n*pas:
    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
    >>> a = 5.0; b = 8.0; n = 5
    >>> x = a
    >>> pas = (b - a)/n
    >>> for _ in range(6):
    ...     x += pas
    ...     print x, x < b, b - x
    ...
    5.6 True 2.4
    6.2 True 1.8
    6.8 True 1.2
    7.4 True 0.6
    8.0 True 1.7763568394e-15
    8.6 False -0.6
    >>> z = a + 5*pas
    >>> b == z
    True
    - W
    Effectivement. Additionner l'imprécision 5 fois provoque 5 arrondis succéssifs alors que 5 * pas ne provoque qu'un seul arrondi.
    Moralité, ne pas envoyer de fusée avec des calculs fait en python.... et betonner ses algos....

  6. #6
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Citation Envoyé par pipodug Voir le message
    Effectivement. Additionner l'imprécision 5 fois provoque 5 arrondis succéssifs alors que 5 * pas ne provoque qu'un seul arrondi.
    Moralité, ne pas envoyer de fusée avec des calculs fait en python.... et betonner ses algos....
    Arghh : tu n'as rien compris !

    Python n'y est pour rien. C'est le codage selon la norme IEEE754 qui est "en cause".

    Les lanceurs, satellites et autres engins spatiaux n'ont pas attendu Python pour, parfois, merder "grave" à cause d'informaticiens qui croyaient que R (nombres réels) matchait parfaitement les flottants !

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 681
    Par défaut
    Citation Envoyé par pipodug Voir le message
    Effectivement. Additionner l'imprécision 5 fois provoque 5 arrondis succéssifs alors que 5 * pas ne provoque qu'un seul arrondi.
    Moralité, ne pas envoyer de fusée avec des calculs fait en python.... et betonner ses algos....
    Python comme tout autre langage ne fait qu'utiliser les instructions machines permettent de faire des opérations sur les nombres dits "à virgule flottante".
    Pour envoyer des fusées ou calculer la résistance des barrages avec les ordinateurs, nous avons développé depuis le milieu du siècle dernier la branche des mathématiques qui s'appelle "calcul numérique".
    Depuis, la loi de Moore a permis de construire des ordinateurs plus puissants qui permettent d'avoir des représentations plus précises. Avec Python, c'est le module decimal qui apporte cela. Les calculs sont plus lents et les représentations consomment plus de mémoire... Mais avec les ordinateurs d'aujourd'hui, c'est acceptable.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre habitué
    Homme Profil pro
    Ingénieur développement informatique scientifique
    Inscrit en
    Janvier 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement informatique scientifique

    Informations forums :
    Inscription : Janvier 2013
    Messages : 10
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Python comme tout autre langage ne fait qu'utiliser les instructions machines permettent de faire des opérations sur les nombres dits "à virgule flottante".
    ...
    Il y a même un chapitre consacré à cette problèmatique dans le tutoriel officiel de Python :https://docs.python.org/3/tutorial/floatingpoint.html

    Cdt,

  9. #9
    Membre averti Avatar de temabul
    Homme Profil pro
    Informatique de Loisir
    Inscrit en
    Février 2015
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Informatique de Loisir

    Informations forums :
    Inscription : Février 2015
    Messages : 26
    Par défaut
    Bonjour,
    Donc en fait, je ne crois pas que ce soit spécifique à python 2.7

Discussions similaires

  1. Comparaison entre deux images: problème de luminosité.
    Par nadour dans le forum Traitement d'images
    Réponses: 3
    Dernier message: 25/03/2014, 11h01
  2. Problème lors q'une comparaison entre 2 valeurs
    Par Xenonmax dans le forum Android
    Réponses: 2
    Dernier message: 15/11/2011, 14h17
  3. Probléme de comparaison entre 2 chaines
    Par boubz013 dans le forum Langage
    Réponses: 17
    Dernier message: 11/11/2010, 23h04
  4. problème entre float et int
    Par F.R.E.D dans le forum Débuter
    Réponses: 2
    Dernier message: 09/09/2008, 02h35
  5. [VBA-E]Problème de comparaison entre plusieurs colonnes
    Par JeanMikael dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 09/07/2007, 17h29

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