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 :

return modulo 0.0. ..1 o_O


Sujet :

Python

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

    Informations forums :
    Inscription : Mars 2010
    Messages : 3
    Par défaut return modulo 0.0. ..1 o_O
    je suis sous Python 2.6.1 et j'ai un problème que je trouve pour le moins insolite mon python ne sait plus divisé correctement même par les puissance de 10.
    ex:

    >>> 685885887558/1000.
    685885887.55799997

    Bon c'est ennuyeux mais pas chiant je me suis débrouillé avec str et float. Et là il ne me renvoi pas le bon résulta.
    mon programme se termine comme suit:

    print res
    return res


    réponse de python :

    53.61
    53.609999999999999

    Donc là je sais vraiment, mais vraiment, plus quoi faire je trouve déjà que j'ai été super concilient avec python.

    help(me)

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Bonsoir,

    Bienvenue sur le forum,


    Ne reproche rien à Python. C’est un problème lié aux contraintes de la représentation binaire des nombres décimaux qui existe pour tous les langages.

    Je vais chercher des posts relativement récent qui ont abordé ce sujet en le décortiquant.



    Mais sache dès maintenant que Python possède un module decimal qui assure une prise en charge de l’arithmétique des nombres décimaux épurée de tous les problèmes de ce genre liés au type float.

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

    Informations forums :
    Inscription : Mars 2010
    Messages : 3
    Par défaut
    ok merci je ne voie pas se que ça change au niveau du return, mais bon ça marche donc je vais pas me plaindre.

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Petits compléments.

    Il ne faut pas confondre calcul et affichage.

    Le calcul est fait avec les nombres tels qu'ils sont stockés en mémoire, et comme cela se fait avec un codage binaire, il est impossible de représenter certains nombres exactement. Mais Python ne fait pas plus mal que les autres langages, puisqu'il utilise les bibliothèques du C...

    L'affichage se fait en transformant le nombres en caractères affichables, c'est à dire en chaines de caractères. Et il y a sous Python deux façons de faire: soit on veut "arranger" l'affichage et on utilise str(x) (c'est ce que print utilise), soit on veut afficher le "vrai" nombre, et on utilise repr(x). Mais c'est le même nombre!

    Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    x = 0.1
    print x
    0.1
    ch = str(x)
    print ch
    0.1
    ch = repr(x)
    print ch
    0.10000000000000001
    NB: au lieu de str(x) et repr(x), on peut utiliser "%s" % (x) et "%r" % (x).

    Dans ton exemple, le return renvoie le "vrai" nombre, celui qu'on utilise pour les calculs. Mais il s'arrange aussi quand on le 'print'. Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    def test(x):
        return x
    x = 0.1
    print test(x)
    0.1
    Mais si print "arrange" un peu l'affichage des nombres réels, il ne le fait pas quand ces nombres se trouvent à l'intérieur d'une liste. Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    x = [0.1, 0.2, [0.3], 0.4]
    print x
    [0.10000000000000001, 0.20000000000000001, [0.29999999999999999], 0.40000000000000002]
    Ça, ce n'est pas chouette...

    Il y a pourtant une solution simple pour afficher correctement une telle liste, il suffit de faire une petite fonction d'affichage récursive:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    def affiche(x):
        ch = ""
        if type(x)==list:
            ch += '['
            for z in x:
                ch += affiche(z) + ', '
            ch = ch[:-2] + ']'
        else:
            ch += "%s" % x
        return ch
     
    print affiche([0.1, 0.2, [0.3], 0.4])
    [0.1, 0.2, [0.3], 0.4]
    On peut, bien entendu, étendre ce principe pour afficher n'importe quel objet de base Python (tuple, dict, complex, ...), et même paramétrer le nombre de chiffres significatifs ainsi que l'encodage des chaines. J'ai essayé de faire un truc comme ça, et c'est ce que j'utilise maintenant couramment (http://python.jpvweb.com/mesrecettespython/printx). Sincèrement, je suis étonné que ça n'existe pas encore intégré dans le Python de base.

    Tyrtamos

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Comme promis sur les calculs de décimaux et le module decimal :


    http://www.python.org/dev/peps/pep-0327/
    PEP publié le 17 Octobre 2003

    http://www.python.org/doc/2.4.1/tut/node16.html
    Doc publiée le 30 mars 2005. Le module decimal est apparu dans Python 2.4

    http://www.python.org/doc/2.4/whatsnew/node9.html
    Docs What's New in Python 2.4 de A.M. Kuchling

    http://docs.python.org/tutorial/floatingpoint.html
    Doc de decimal dans la doc Python 2.6.5c1 apparue le 03/03/2010

    http://docs.python.org/3.1/tutorial/floatingpoint.html
    Dernière doc



    Quelques autres liens

    http://www.developpez.net/forums/d86...hon/max-bugge/

    http://www.developpez.net/forums/d87...hon/map-round/

    http://wikipython.flibuste.net/CalculerJuste

    http://www.lahey.com/float.htm

    http://www.ibm.com/developerworks/wi...Floating+Point

    http://www.google.fr/url?q=http://ww...st0CZ8XMxIJedA

    http://speleotrove.com/decimal/





    --------------------------------------




    Tyrtamos +1 pour les remarques et pour printx sur ton site
    Je n’ai pas tout étudié. Mais je propose la simplification suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    li = [0.456,[0.44,1.4],10.8]
    print 'li          =',li
    print '\nstr(li)     =',str(li)
    print '\nrepr(li)    =',repr(li)
     
    def affiche(x):
        if type(x)==list:
            return map(affiche,x)
        return str(x)
     
    print '\naffiche(li) =',affiche(li)

    EDIT
    J’avais écrit que dans Python 3, il faut écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return list(map(affiche,x))
    parce que map() est un itérateur dans Python 3.
    Mais justement, non, c’est faux puisque le principe de la fonction récursive affiche() c’est de toujours sortir en bout de course un str(x) avec x = un nombre.
    N'ayant pas installé Python 3, je ne peux pas vérifier et c'est pour ça que je m’étais trompé, mais je pense que c'est ainsi.

  6. #6
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Merci pour ta remarque eyquem. J'essaye de ne pas trop utiliser les fonctions comme map qui changent de fonctionnement avec Python 3 pour faciliter l'évolution de mes codes.

    En ce qui concerne le module decimal, on arrive à faire des choses étonnantes avec, mais ce n'est pas toujours très pratique à utiliser et ça manque un peu de fonctions mathématiques.

    Du coup, j'ai commencé à créer les fonctions transcendantes traditionnelles (en partant des séries) et j'arrive à de très bon résultats. Je n'ai pas terminé, mais c'est bien avancé: http://python.jpvweb.com/mesrecettespython/math_decimal.

    Avec ces fonctions, calculer un sinus ou un logarithme ou même pi ou e avec 1000 chiffres significatifs n'est plus un problème. Et même si ça n'a pas beaucoup d'intérêt pratique, c'est très amusant à faire...

    Tyrtamos

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

Discussions similaires

  1. [pl/pgSQL 7.2] Returns Opaque?
    Par Gruik dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 18/10/2003, 16h50
  2. return ();exit() ;
    Par Zazeglu dans le forum C
    Réponses: 12
    Dernier message: 10/10/2003, 20h56
  3. [C#] Changer le focus avec la touche return
    Par sblanc74 dans le forum Windows Forms
    Réponses: 6
    Dernier message: 01/10/2003, 18h38
  4. return
    Par drKzs dans le forum C
    Réponses: 3
    Dernier message: 18/09/2003, 22h36
  5. Modulo en Assembleur
    Par SteelBox dans le forum Assembleur
    Réponses: 10
    Dernier message: 07/04/2003, 22h49

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