4
votes

Vérifiez si Python Decimal se termine par une certaine valeur

J'ai un tas d'objets Decimal. Je veux tester chacun d'eux pour voir s'il se termine par .43 . Je peux le faire en le convertissant d'abord en une chaîne:

>>> num = Decimal('1.4321')
>>> '.43' in str(num)
True

Mais cela échoue si je ne sais pas avec quelle précision le Decimal a été créé.

>>> num = Decimal('1.4300')
>>> '.43' in str(num)
True


4 Réponses :


6
votes

Il sera préférable d'utiliser ici le raisonnement mathématique, en évitant le domaine float (inexact) et le domaine string (inutile). Si vous soustrayez 0.43 d'un nombre se terminant par .43 , vous devriez être laissé avec un entier, et vous pouvez vérifier cela en utilisant l'opérateur modulo % :

>>> point43 = Decimal("0.43") 
>>> num = Decimal('1.43') 
>>> (abs(num) - point43) % 1 == 0 
True


0 commentaires

2
votes

Vous pouvez profiter de l'opérateur module comme ceci:

(L'opérateur module ici supprime la valeur entière. 32.48% 1 se transforme en 0.48 . L'absolu value la rend positive. abs (-32.48) deviendra 32.48 . Merci @wim.)

>>> num = float('1.4300')       # changes input into float (removes trailing 0s automatically)
>>> round(abs(num)%1, 2) == .43 # checks if it ends with .43 with 2 decimal points
True

p >


6 commentaires

Vrai. Je vais arranger ça.


... Je suppose que la vôtre utilise sa classe Decimal personnalisée où la mienne dit simplement non. Euh ...


J'ai essayé l'opérateur de module en python 3 et pour 1,340, il renvoie 0,3400000001 et donc, en comparant avec 0,34, il échoue. Tu sais pourquoi?


J'hésiterais à appeler cela «correct»; comparer deux float s pour l'égalité est sensible à l'erreur d'arrondi. La réponse de @ wim garantit que toutes les opérations continuent d'être effectuées sur des valeurs Decimal .


Je pense que ma réponse est susceptible d'erreurs d'arrondi. Je vais encore arrondir: |


@GeeTransit Ce n'est pas le seul problème; vous ne pouvez pas supposer que le littéral flottant 0.43 est exact en premier lieu. Regardez le résultat de Decimal (0.43) par rapport à Decimal ("0.43") pour voir le problème.



2
votes

Vous pouvez convertir en chaîne puis supprimer les 0 de fin avant de vérifier comme suit.

num = Decimal('1.4300')
print(str(num).rstrip('0').endswith('.43'))
#Prints True


0 commentaires

0
votes

Vous pouvez supprimer votre chaîne de zéros

>>> num = Decimal('1.4300')
>>> str(num).strip('0').endswith('.43')
True


0 commentaires