Kaydet (Commit) ced6b1da authored tarafından Raymond Hettinger's avatar Raymond Hettinger

Update the decimal FAQ for the from_float() classmethod and improve the recipe…

Update the decimal FAQ for the from_float() classmethod and improve the recipe for remove_exponent() to make it cut and pasteable.
üst daeceb2d
...@@ -1907,47 +1907,28 @@ of significant places in the coefficient. For example, expressing ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment