#1 Le 26/02/2013, à 23:03
- naingenieu
[RESOLU][Python] Très grands nombre à virgule
Bonsoir / Bonjour tout le monde
Je viens à vous avec un petit soucis rencontré au cours d'un développement en Python.
Je suis en train de faire une application qui doit traiter avec de très grands nombres ( jusqu'à 128 ^ 31 ) mais ces nombres doivent aussi avoir une virgule. Or Python transforme automatiquement les très grands nombres flottants en 2.138384392e64 et le retour en int me donne un chiffre erroné. Je me suis renseigné et je sais que ce n'est pas possible d'être très précis avec les nombres à virgule flottante ( de ce que j'ai compris de la doc ) ce qui ne m'arrange pas du tout ( pour des raisons évidentes de précision )
>>> float(11111111111111111111111111111111111111111111111111111111111111111)
1.1111111111111111e+64
>>> int(float(11111111111111111111111111111111111111111111111111111111111111111))
11111111111111111023226514031514872313639569077136717262840922112L
J'ai aussi essayé avec le module decimal et fraction sans succès ....
>>> from decimal import Decimal
>>> Decimal('1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.1')
Decimal('1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.1')
>>> a = Decimal('11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.1')
>>> a+a
Decimal('2.222222222222222222222222222E+133')
>>> Fraction(1.5)
Fraction(3, 2)
>>> Fraction(111111111111111111111111111111111111111111111111111111111111)
Fraction(111111111111111111111111111111111111111111111111111111111111, 1)
>>> Fraction(111111111111111111111111111111111111111111111111111111111111.1)
Fraction(111111111111111115398901787910723492567390900178539566333952, 1)
J'ai aussi pensé à créer une classe qui retient d'un côté le nombre avec la virgule et de l'autre la partie entière malheureusement je dois effectuer des multiplications ( et des divisions ) et donc l'on risque de retrouver le même problème ....
Quelqu'un aurait une solution? Une libraire mystérieuse? Une classe miracle? Une actuce quelconque?
J'utilise actuellement python 2.7 mais je peut passer ce code sous python 3.X sans aucun soucis
Bonne soirée et merci d'avance
Dernière modification par naingenieu (Le 27/02/2013, à 10:45)
Hors ligne
#2 Le 27/02/2013, à 04:51
- grim7reaper
Re : [RESOLU][Python] Très grands nombre à virgule
Salut,
Tu utilises Python 3 ou Python 2 ?
Dans tout les cas, ça fonctionne bien de base, sans rien ajouter :
grim7reaper@morning ~]$python3
Python 3.2.3 (default, Oct 19 2012, 19:53:16)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 128**31
>>> a
210624583337114373395836055367340864637790190801098222508621955072
>>>
grim7reaper@morning ~]$python
Python 2.7.3 (default, Sep 26 2012, 21:51:14)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 128**31
>>> a
210624583337114373395836055367340864637790190801098222508621955072L
Donc il faudrait en savoir plus sur ton code pour savoir d’où viens le problème.
Hors ligne
#3 Le 27/02/2013, à 07:24
- pingouinux
Re : [RESOLU][Python] Très grands nombre à virgule
Bonjour,
Voir aussi le module fractions.
Help on module fractions:
NAME
fractions - Rational, infinite-precision, real numbers.
Hors ligne
#4 Le 27/02/2013, à 07:26
- lann
Re : [RESOLU][Python] Très grands nombre à virgule
Peut-être que ce paquet pourrait t'intéresser : python-gmpy
Avec l'adresse du projet : http://www.aleax.it/gmpy.html
<Modéré>
Hors ligne
#5 Le 27/02/2013, à 08:52
- tiramiseb
Re : [RESOLU][Python] Très grands nombre à virgule
Et si tu veux des calculs précis, utilise Decimal. Tu dis que tu as essayé sans succès, mais tu n'as pas détaillé en quoi tu as échoué...
sebastien@cao:~$ python
Python 2.7.3 (default, Sep 26 2012, 21:51:14)
>>> from decimal import Decimal
>>> 123456723414564567478467432342656235636356356532635622356735672357257357635273576235635635263563524325236764786894536573263457634849684945.32767968374564123542346763487696846457624132637865790486798563764
1.2345672341456457e+137
>>> Decimal('123456723414564567478467432342656235636356356532635622356735672357257357635273576235635635263563524325236764786894536573263457634849684945.32767968374564123542346763487696846457624132637865790486798563764')
Decimal('123456723414564567478467432342656235636356356532635622356735672357257357635273576235635635263563524325236764786894536573263457634849684945.32767968374564123542346763487696846457624132637865790486798563764')
>>> str(Decimal('123456723414564567478467432342656235636356356532635622356735672357257357635273576235635635263563524325236764786894536573263457634849684945.32767968374564123542346763487696846457624132637865790486798563764'))
'123456723414564567478467432342656235636356356532635622356735672357257357635273576235635635263563524325236764786894536573263457634849684945.32767968374564123542346763487696846457624132637865790486798563764'
(ici j'ai pris un nombre totalement arbitraire, hyper long et à virgule)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#6 Le 27/02/2013, à 10:29
- naingenieu
Re : [RESOLU][Python] Très grands nombre à virgule
Merci à tous pour vos réponses :
@grim7reaper : oui je sais que python gère les entiers arbitrairement longs mais pas les flottants, ainsi
>>> float(11111111111111111111111111111111111111111111111111111111111111111)
1.1111111111111111e+64
>>> int(float(11111111111111111111111111111111111111111111111111111111111111111))
11111111111111111023226514031514872313639569077136717262840922112L
Ce qui n'est pas très pratique ....
@pingouinux :
j'ai aussi essayé le module Fraction ( j'avais oublié de préciser désolé ) mais il ne donne pas de résultats satisfaisants, ainsi :
>>> Fraction(1.5)
Fraction(3, 2)
>>> Fraction(111111111111111111111111111111111111111111111111111111111111)
Fraction(111111111111111111111111111111111111111111111111111111111111, 1)
>>> Fraction(111111111111111111111111111111111111111111111111111111111111.1)
Fraction(111111111111111115398901787910723492567390900178539566333952, 1)
@tiramiseb oui désolé je n'ai pas mis des exemples de code. Decimal permet effectivement de sauvegarder correctement les nombres mais pas de faire des opérations avec, par exemple :
>>> from decimal import Decimal
>>> Decimal('1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.1')
Decimal('1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.1')
>>> a = Decimal('11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.1')
>>> a+a
Decimal('2.222222222222222222222222222E+133')
ce qui est problématique
@Iann :
Merci je vais essayer ça tout de suite
Au fait je ne l'ai pas précisé mais j'utilise python 2.7 ( mais si jamais il le faut le code peut passer en python3 sans grand soucis )
Dernière modification par naingenieu (Le 27/02/2013, à 10:32)
Hors ligne
#7 Le 27/02/2013, à 10:36
- tiramiseb
Re : [RESOLU][Python] Très grands nombre à virgule
@tiramiseb oui désolé je n'ai pas mis des exemples de code. Decimal permet effectivement de sauvegarder correctement les nombres mais pas de faire des opérations avec, par exemple :
>>> from decimal import Decimal >>> Decimal('1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.1') Decimal('1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.1') >>> a = Decimal('11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.1') >>> a+a Decimal('2.222222222222222222222222222E+133')
Il faut configurer sa précision :
>>> from decimal import Decimal, getcontext
>>> getcontext().prec = 500
>>> a = Decimal('11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.1')
>>> a+a
Decimal('22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222.2')
Voir dans l'introduction de la documentation de ce module : http://docs.python.org/2/library/decimal.html
Unlike hardware based binary floating point, the decimal module has a user alterable precision (defaulting to 28 places) which can be as large as needed for a given problem
... avec un exemple juste en-dessous...
EDIT : un exemple avec la précision au plus près...
>>> a = Decimal('11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.1')
>>> getcontext().prec = len(str(a).replace('.', ''))
>>> a + a
Decimal('22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222.2')
>>> getcontext().prec = len(str(a).replace('.', '')) - 1
>>> a + a
Decimal('22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222')
>>>
Dernière modification par tiramiseb (Le 27/02/2013, à 10:42)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#8 Le 27/02/2013, à 10:45
- naingenieu
Re : [RESOLU][Python] Très grands nombre à virgule
@tiramiseb : Merci beaucoup
Désolé de pas avoir bien lu la doc ....
Je passe en résolu
En fait je sais d'où vient l'erreur, quand j'avais testé Decimal, j'avais bien fait attention à modifier la précision mais je rentrais mes nombres en tant que nombres et non que chaines de caractères
Merci encore !
Hors ligne
#9 Le 27/02/2013, à 10:55
- pingouinux
Re : [RESOLU][Python] Très grands nombre à virgule
mais je rentrais mes nombres en tant que nombres et non que chaines de caractères
Pour info, c'est vrai aussi avec fractions
>>> fractions.Fraction(111111111111111111111111111111111111111111111111111111111111.1)
Fraction(111111111111111115398901787910723492567390900178539566333952, 1)
>>> fractions.Fraction("111111111111111111111111111111111111111111111111111111111111.1")
Fraction(1111111111111111111111111111111111111111111111111111111111111, 10)
Hors ligne
#10 Le 27/02/2013, à 11:02
- naingenieu
Re : [RESOLU][Python] Très grands nombre à virgule
@pingouinux Mea Culpa
Hors ligne