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 :

Conversion float to integer


Sujet :

Python

  1. #1
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2010
    Messages : 662
    Par défaut Conversion float to integer
    Bonjour tout le monde,

    Il y a un truc que je ne comprends pas avec la conversion d'un double (flottant) vers un entier avec la fonction int:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> n = 41063625
    >>> print n**(1./3), int(n**(1./3))
    345.0 344
    >>> print int(345.0)
    345


    Python 2.7

    Julien

  2. #2
    Membre confirmé
    Homme Profil pro
    Ingénieur calcul et simulation
    Inscrit en
    Juin 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Ingénieur calcul et simulation
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2013
    Messages : 41
    Par défaut
    Bonjour,

    A priori, ce serai du à une erreur de représentation du float, comme expliqué ici http://stackoverflow.com/questions/6...ersion-problem

  3. #3
    Expert confirmé

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

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

    En plus de la cause donnée par Aegim, il y a aussi une différence de comportement avec print

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    >>> d = 1./3
    >>> d
    0.3333333333333333
    >>> 41063625 ** d
    344.9999999999999
    >>> print 41063625 ** d
    345.0

  4. #4
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2010
    Messages : 662
    Par défaut
    Hmm, c'est quelque chose que j'aurais du savoir. Merci à toi Aegim pour le lien.

    Je vais jeter un oeil plus en détail au document suivant:
    http://http://docs.oracle.com/cd/E19..._goldberg.html

    @ VinsS
    Oui c'est ça qui m'a perturbé, l'affichage de 345.0 (solution exacte).

    Peut-être cela vous semblait-il evident au vu du code que j'ai fourni. Je cherche à verifier si le résultat d'une operation (en l'occurence la racine cubique d'un entier) est un entier. La methode que j'emploie en toujours la meme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if n == int(n):
        print "OK c'est un entier"
    Est-ce que par hasard vous connaissez une autre methode? Qui n'aurait pas le même problème.

    Ciao

    Ju

  5. #5
    Membre confirmé
    Homme Profil pro
    Ingénieur calcul et simulation
    Inscrit en
    Juin 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Ingénieur calcul et simulation
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2013
    Messages : 41
    Par défaut
    J'ai pu trouver ce code qui a priori donne le bon résultats sans passer par des floats :

    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
    def cube_root(n): 
        "A modified Newton's Method solver for integral cube roots." 
        if int(n) != n : 
            raise ValueError("must provide an integer") 
        if n in (-1,0,1): return n 
        offset = (1,-1)[n > 0] 
        x = n/2 
        seen = set() 
        steps = 0 
        while 1: 
            y = x**3 
            if y == n: 
                return x 
            dydx = 3.0*x*x 
            x += int((n-y)/dydx)+offset 
            x = x or 1 
            if x in seen: 
                raise ValueError("%d is not a perfect cube" % n) 
            seen.add(x) 
            steps += 1
    Le code vient de http://python.6.x6.nabble.com/cube-r....html#a1733529 et marche avec quelques essais. Ca pourrait donc être ce dont tu as besoin.

  6. #6
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    racine cubique(8) -> 2 mais 2**3 -> 8

    Pourquoi ne pas travailler avec les entiers plutôt que des flottants ?

  7. #7
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2010
    Messages : 662
    Par défaut
    @Aegim
    C'est une solution, mais assez... compliquée!

    @fred1599
    Bonne remarque. De temps en temps je resouds quelques excercices d'un jeu en ligne appelé "Poject Euler". ça me permet de me perfectionner et de découvrir des subtilités et methodes de calculs. Je crois que je ne suis pas le seul sur ce forum à le faire.

    Le sujet que je traite est simple. On prend un entier n que l'on élève au cube. On cherche à trouver si parmi toutes les permutations possible du nombre resultant il existe d'autres racines cubiques entières et combien:

    ex:
    345**3 --> 41063625
    384**3 --> 56623104
    405**3 --> 66430125
    56623104 et 66430125 des permutations de 41063625
    Bon le sujet de ce poste n'est pas la resolution du problème du jeu, hein, laissez le moi!

    Ju

  8. #8
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Pourquoi ne pas utiliser le module itertools, il est fait pour ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    >>> from itertools import permutations as perm
    >>> def permut(n):
    ...     n = str(n)
    ...     size = len(n)
    ...     for i in perm(n, size):
    ...         yield ''.join(i)
    ... 
    >>> print('\n'.join(permut(123)))
    123
    132
    213
    231
    312
    321
    Bonne continuation...

  9. #9
    Membre confirmé
    Homme Profil pro
    Ingénieur calcul et simulation
    Inscrit en
    Juin 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Ingénieur calcul et simulation
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2013
    Messages : 41
    Par défaut
    Je reconnais que c'est pas vraiment simple ^^

    En plus simple (mais un peu brute), tu peux aussi faire dans un premier temps comme tu faisais initialement avec int. Et ensuite tu testes pour le résultat obtenu (344 dans ton exemple), le résultat +1 (ici 345)et le résultat -1 (343) si le cube est égale à ta valeur de départ. Comme ça en cas d'arrondi raté dans un sens ou dans l'autre tu t'y retrouves.
    C'est loin d'être élégant comme solution, mais c'est plus simple ^^'

  10. #10
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    En plus simple (mais un peu brute), tu peux aussi faire dans un premier temps comme tu faisais initialement avec int. Et ensuite tu testes pour le résultat obtenu (345 dans ton exemple), le résultat +1 (ici 346)et le résultat -1 (343) si le cube est égale à ta valeur de départ. Comme ça en cas d'arrondi raté dans un sens ou dans l'autre tu t'y retrouves.
    C'est loin d'être élégant comme solution, mais c'est plus simple ^^'
    Non non c'est juste la bonne solution

  11. #11
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2010
    Messages : 662
    Par défaut
    @Fred1599
    J'utilise bien évidemment itertools

    @Aegim
    J'ai continué à fouiller sur le net. On trouve pas mal de sujets abordant la racine carrée. J'ai retrouvé notamment un thread sur stackoverflow avec un algo similaire à celui que tu propose.

    En voici un autre utilisant le module decimal qui après quelques tests semble aussi fonctionner:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    from decimal import Decimal,localcontext
    from math import exp,log
     
    def iscube(n):
        nd = Decimal(n)
        with localcontext() as ctx:
            ctx.prec = n.bit_length()
            i = int(exp(log(nd)*(1./3)))
        if i**3 != n:
            raise ValueError('input was not a perfect cube')
        return i
    Il y a une astuce, visiblement le module decimal ne permet pas encore les puissances non entières, d'où le passage par le log...

    Bref, je suis capable maintenant de verifier si une des permutations est également le resultat d'un entier au cube. Je vais garder en mémoire ce problème sur la precision des flottants. Je suis sûr que j'aurais un de ces quatre ce problème à nouveau.

    Merci à tous les deux pour vos réponses rapides. A moins que vous ne souhaitiez rajouter quelque chose je passerais en résolu.

    Ciao

    Ju

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

Discussions similaires

  1. [Sunopsis] Problème de conversion float -> integer
    Par kergoussel dans le forum Alimentation
    Réponses: 3
    Dernier message: 05/12/2007, 14h47
  2. Conversion float vers int
    Par vargasvan dans le forum C
    Réponses: 2
    Dernier message: 05/10/2005, 17h29
  3. conversion text vers integer
    Par jawad.t dans le forum Connexion aux bases de données
    Réponses: 3
    Dernier message: 10/06/2005, 20h35
  4. Réponses: 3
    Dernier message: 12/05/2005, 12h10
  5. Conversions de String à Integer
    Par Rank dans le forum Langage
    Réponses: 5
    Dernier message: 06/08/2003, 16h30

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