2015-11-26 2 views
2

La meilleure façon j'ai trouvé pour produire un nombre decimal.Decimal avec un nombre spécifique de significant figures est celui qui est utilisé pour initialiser la variable kluge ci-dessous:Comment créer un objet decimal.Decimal avec un nombre donné de chiffres significatifs?

import decimal 
THIS_IS_JUST_AN_EXAMPLE = 0.00001/3.0 
with decimal.localcontext() as c: 
    c.prec = 5 
    kluge = decimal.Decimal(THIS_IS_JUST_AN_EXAMPLE) + decimal.Decimal(0) 
    naive = decimal.Decimal(THIS_IS_JUST_AN_EXAMPLE) 
    print repr(kluge) 
    print repr(naive) 

# Decimal('0.0000033333') 
# Decimal('0.00000333333333333333374718233758915442166426146286539733409881591796875') 

La première ligne de sortie représente le nombre souhaité decimal.Decimal , avec 5 chiffres significatifs. La deuxième ligne de la sortie montre ce qui se passe si on n'ajoute pas le

+ decimal.Decimal(0) 

l'ERS de l'initialisation; sans cela, le résultat a une précision excessive non désirée et inutile.

Même sans le hack + decimal.Decimal(0), le code me semble plus bavard qu'il ne devrait l'être.

Quelle est l'approche correcte pour créer un Decimal avec un nombre désiré de chiffres significatifs?


Cette question n'est pas un double de Format Python Decimal object to a specified precision. Regardez la sortie ci-dessous.

import math 
import decimal 
base = math.pi 
with decimal.localcontext() as c: 
    c.prec = 13 
    for exponent in [6, 4, 2, 0, -2, -4, -6]: 
     scale = 10**exponent 
     kluge = decimal.Decimal(base * scale) + decimal.Decimal(0) 
     print repr(kluge) 

# Decimal('3141592.653590') 
# Decimal('31415.92653590') 
# Decimal('314.1592653590') 
# Decimal('3.141592653590') 
# Decimal('0.03141592653590') 
# Decimal('0.0003141592653590') 
# Decimal('0.000003141592653590') 

Les éléments affichés dans la sortie ci-dessus ne peuvent être obtenus en utilisant la méthode donnée dans la réponse à Format Python Decimal object to a specified precision, tout simplement parce que cette question n'a rien à voir avec le formatage de sortie.

Cette question est sur la façon d'utiliser un pour créer certains objets d'une classe définie par ce module module spécifique (decimal). Plus précisément, il s'agit de chercher un moyen d'utiliser le module decimal pour obtenir le résultat affiché sans avoir à ajouter decimal.Decimal(0).

Répondre

3

Vous semblez être à la recherche Context.create_decimal:

Crée une nouvelle instance décimale de num mais en utilisant auto comme contexte. Contrairement au constructeur Decimal, la précision du contexte, la méthode d'arrondi , les indicateurs et les interruptions sont appliqués à la conversion.

>>> decimal.Context(prec=5).create_decimal(0.00001/3.0) 
Decimal('0.0000033333') 
+0

Merci. J'avais initialement accepté cette réponse, mais par la suite j'ai découvert des entrées (pas du tout inhabituelles) pour lesquelles cette méthode ne produit pas le bon nombre de chiffres significatifs. (http://stackoverflow.com/questions/34211451/possible-bug-in-decimal) – kjo

+0

@kjo: Oh hé, vous êtes le même gars de l'autre question. Je n'ai pas remarqué. Si vous voulez des zéros à la fin, vous pouvez les obtenir, mais cela commence à ressembler à un problème qui devrait être traité dans la logique d'affichage plutôt que dans la représentation interne. Puisque vous avez spécifiquement souligné que ce n'est pas un problème d'affichage, j'ai interprété cela comme une question d'arrondi, où les zéros de fin ne seraient pas importants. De quoi avez-vous besoin de zéros à la fin? – user2357112

+0

Les zéros finaux découlent de la définition des "chiffres significatifs". Je commence à réaliser, à ma grande stupéfaction, que Python ignore le concept de "figures significatives" ... – kjo