Des précisions sur le type Décimal en Python

Tout le monde sait, ou au moins, tous les programmeurs doivent savoir, que l'utilisation de la float type pourrait conduire à des erreurs de précision. Toutefois, dans certains cas, une solution exacte serait bien et il ya des cas où la comparaison à l'aide d'une valeur epsilon n'est pas assez. De toute façon, ce n'est pas vraiment le point.

Je savais à propos de la Decimal type en Python, mais je n'ai jamais essayé de l'utiliser. Il affirme que "Décimal les nombres peuvent être représentés exactement" et j'ai pensé qu'il s'agissait d'une habile mise en œuvre qui permet de représenter n'importe quel nombre réel. Mon premier essai était:

>>> from decimal import Decimal
>>> d = Decimal(1) / Decimal(3)
>>> d3 = d * Decimal(3)
>>> d3 < Decimal(1)
True

Assez déçu, je suis rentré à la documentation et à gardé lecture:

Le contexte de l'arithmétique est un environnement de spécification de précision [...]

Ok, donc il y a effectivement une précision. Et les questions classiques qui peuvent être reproduites:

>>> dd = d * 10**20
>>> dd
Decimal('33333333333333333333.33333333')
>>> for i in range(10000):
...    dd += 1 / Decimal(10**10)
>>> dd
Decimal('33333333333333333333.33333333')

Donc, ma question est: est-il un moyen d'avoir un type Décimal avec une précision infinie? Si non, quel est le moyen plus élégant de la comparaison de 2 nombres décimaux (p. ex. d3 < 1 doit retourner False si le delta est inférieur à la précision).

Actuellement, quand je ne fais que des divisions et des multiplications, j'utilise le Fraction type:

>>> from fractions import Fraction
>>> f = Fraction(1) / Fraction(3)
>>> f
Fraction(1, 3)
>>> f * 3 < 1
False
>>> f * 3 == 1
True

Est-il la meilleure approche? Quelles pourraient être les autres options?

  • comment voulez-vous vous représenter Pi avec votre hypothétique de type Décimal?
  • connexes: Comment est-il dangereux pour comparer les valeurs à virgule flottante?
  • Je ne serais pas surpris si possible. C'est pourquoi je pose la question "quel est le moyen plus élégant de la comparaison de 2 nombres décimaux".
  • Je pense aussi à un type qui me permettent de nombreuses manipulations (opérations de base, des fonctions communes, etc), mais de garder une représentation exacte. Par exemple, la Fraction type semble gérer parfaitement de nombreux cas. En fait, toute fois, le résultat n'est pas un nombre irrationnel. Mais peut-être qu'on pourrait faire mieux avec une autre représentation qui permettrait d'inclure un plus grand sous-ensemble. Quelque chose de dynamique, de précision, comme un gamin le ferait à l'école par exemple. Bien sûr, je ne pouvais pas représenter Pi, mais assez souvent, Pi est juste une constante du problème.
  • Avant de réinventer la roue avec votre représentation exacte, jetez un oeil à la Sauge ou sympy
  • J'ai été la lecture de la documentation de SymPy, mais je ne peux pas trouver un type (qui pourrait remplacer directement en Décimal). Mais en effet, SymPy, qui n'calcul symbolique, pourrait sans doute faire l'affaire.