mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
Update the decimal FAQ for the from_float() classmethod and improve the recipe for remove_exponent() to make it cut and pasteable.
This commit is contained in:
parent
daeceb2de8
commit
ced6b1da83
1 changed files with 15 additions and 34 deletions
|
@ -1907,47 +1907,28 @@ of significant places in the coefficient. For example, expressing
|
||||||
original's two-place significance.
|
original's two-place significance.
|
||||||
|
|
||||||
If an application does not care about tracking significance, it is easy to
|
If an application does not care about tracking significance, it is easy to
|
||||||
remove the exponent and trailing zeroes, losing significance, but keeping the
|
remove the exponent and trailing zeros, losing significance, but keeping the
|
||||||
value unchanged:
|
value unchanged::
|
||||||
|
|
||||||
>>> def remove_exponent(d):
|
def remove_exponent(d):
|
||||||
... return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()
|
'''Remove exponent and trailing zeros.
|
||||||
|
|
||||||
>>> remove_exponent(Decimal('5E+3'))
|
>>> remove_exponent(Decimal('5E+3'))
|
||||||
Decimal('5000')
|
Decimal('5000')
|
||||||
|
|
||||||
Q. Is there a way to convert a regular float to a :class:`Decimal`?
|
'''
|
||||||
|
return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()
|
||||||
|
|
||||||
A. Yes, all binary floating point numbers can be exactly expressed as a
|
Q. Is there a way to convert a regular float to a Decimal?
|
||||||
Decimal. An exact conversion may take more precision than intuition would
|
|
||||||
suggest, so we trap :const:`Inexact` to signal a need for more precision:
|
|
||||||
|
|
||||||
.. testcode::
|
A. Yes, the classmethod :meth:`from_float` makes an exact conversion.
|
||||||
|
|
||||||
def float_to_decimal(f):
|
The regular decimal constructor does not do this by default because there is
|
||||||
"Convert a floating point number to a Decimal with no loss of information"
|
some question about whether it is advisable to mix binary and decimal floating
|
||||||
n, d = f.as_integer_ratio()
|
point. Also, its use requires some care to avoid the representation issues
|
||||||
numerator, denominator = Decimal(n), Decimal(d)
|
associated with binary floating point:
|
||||||
ctx = Context(prec=60)
|
|
||||||
result = ctx.divide(numerator, denominator)
|
|
||||||
while ctx.flags[Inexact]:
|
|
||||||
ctx.flags[Inexact] = False
|
|
||||||
ctx.prec *= 2
|
|
||||||
result = ctx.divide(numerator, denominator)
|
|
||||||
return result
|
|
||||||
|
|
||||||
.. doctest::
|
>>> Decimal.from_float(1.1)
|
||||||
|
|
||||||
>>> float_to_decimal(math.pi)
|
|
||||||
Decimal('3.141592653589793115997963468544185161590576171875')
|
|
||||||
|
|
||||||
Q. Why isn't the :func:`float_to_decimal` routine included in the module?
|
|
||||||
|
|
||||||
A. There is some question about whether it is advisable to mix binary and
|
|
||||||
decimal floating point. Also, its use requires some care to avoid the
|
|
||||||
representation issues associated with binary floating point:
|
|
||||||
|
|
||||||
>>> float_to_decimal(1.1)
|
|
||||||
Decimal('1.100000000000000088817841970012523233890533447265625')
|
Decimal('1.100000000000000088817841970012523233890533447265625')
|
||||||
|
|
||||||
Q. Within a complex calculation, how can I make sure that I haven't gotten a
|
Q. Within a complex calculation, how can I make sure that I haven't gotten a
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue