Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
845 views
in Technique[技术] by (71.8m points)

python - How to create a decimal.Decimal object with a given number of significant figures?

The best way I've found to produce a decimal.Decimal number with a specific number of significant figures is the one used to initialize the variable kluge below:

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')

The first line of output shows the desired decimal.Decimal number, with 5 significant figures. The second line in the output shows what happens if one does not add the

+ decimal.Decimal(0)

to the RHS of the initialization; without it, the result has unwanted and unhelpful excess precision.

Even without the + decimal.Decimal(0) hack, the code strikes me as more verbose than it needs to be.

What's the correct approach to creating a Decimal with a desired number of significant figures?


This question is not a duplicate of Format Python Decimal object to a specified precision. Look at the output below.

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')

The items shown in the output above cannot be obtained using the method given in the answer to Format Python Decimal object to a specified precision, simply because this question has nothing to do with formatting output.

This question is about how to use a specific module (decimal) to create certain objects of a class defined by that module. More specifically, it is about looking for a way to use the decimal module to achieve the result shown without having to resort to adding decimal.Decimal(0).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You seem to be looking for Context.create_decimal:

Creates a new Decimal instance from num but using self as context. Unlike the Decimal constructor, the context precision, rounding method, flags, and traps are applied to the conversion.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...