Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 66cb7d4

Browse files
committed
Simplify float conversion recipe.
1 parent 65baa34 commit 66cb7d4

1 file changed

Lines changed: 18 additions & 28 deletions

File tree

Doc/library/decimal.rst

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,39 +1516,29 @@ Q. Is there a way to convert a regular float to a :class:`Decimal`?
15161516

15171517
A. Yes, all binary floating point numbers can be exactly expressed as a
15181518
Decimal. An exact conversion may take more precision than intuition would
1519-
suggest, so trapping :const:`Inexact` will signal a need for more precision::
1520-
1521-
def floatToDecimal(f):
1522-
"Convert a floating point number to a Decimal with no loss of information"
1523-
# Transform (exactly) a float to a mantissa (0.5 <= abs(m) < 1.0) and an
1524-
# exponent. Double the mantissa until it is an integer. Use the integer
1525-
# mantissa and exponent to compute an equivalent Decimal. If this cannot
1526-
# be done exactly, then retry with more precision.
1527-
1528-
mantissa, exponent = math.frexp(f)
1529-
while mantissa != int(mantissa):
1530-
mantissa *= 2.0
1531-
exponent -= 1
1532-
mantissa = int(mantissa)
1533-
1534-
oldcontext = getcontext()
1535-
setcontext(Context(traps=[Inexact]))
1536-
try:
1537-
while True:
1538-
try:
1539-
return mantissa * Decimal(2) ** exponent
1540-
except Inexact:
1541-
getcontext().prec += 1
1542-
finally:
1543-
setcontext(oldcontext)
1544-
1545-
Q. Why isn't the :func:`floatToDecimal` routine included in the module?
1519+
suggest, so we trap :const:`Inexact` to signal a need for more precision::
1520+
1521+
def float_to_decimal(f):
1522+
"Convert a floating point number to a Decimal with no loss of information"
1523+
n, d = f.as_integer_ratio()
1524+
with localcontext() as ctx:
1525+
ctx.traps[Inexact] = True
1526+
while True:
1527+
try:
1528+
return Decimal(n) / Decimal(d)
1529+
except Inexact:
1530+
ctx.prec += 1
1531+
1532+
>>> float_to_decimal(math.pi)
1533+
Decimal("3.141592653589793115997963468544185161590576171875")
1534+
1535+
Q. Why isn't the :func:`float_to_decimal` routine included in the module?
15461536

15471537
A. There is some question about whether it is advisable to mix binary and
15481538
decimal floating point. Also, its use requires some care to avoid the
15491539
representation issues associated with binary floating point::
15501540

1551-
>>> floatToDecimal(1.1)
1541+
>>> float_to_decimal(1.1)
15521542
Decimal("1.100000000000000088817841970012523233890533447265625")
15531543

15541544
Q. Within a complex calculation, how can I make sure that I haven't gotten a

0 commit comments

Comments
 (0)