leo-the-manic - 1 year ago 70
Python Question

# Best way to convert fractions.Fraction to decimal.Decimal?

In Python, the

`fractions.Fraction`
and
`decimal.Decimal`
standard library classes exist to help keep arithmetic with rational numbers precise. For the unfamiliar, an example of where it helps:

``````>>> 1 / 10 * 3
0.30000000000000004
>>> decimal.Decimal('1') / 10 * 3
Decimal('0.3')
>>> fractions.Fraction('1') / 10 * 3
Fraction(3, 10)
``````

My question is, if I have a
`Fraction`
, what's the best way to convert it to a
`Decimal`
?

Unfortunately the obvious solution doesn't work:

``````>>> decimal.Decimal(fractions.Fraction(3, 10))
Traceback (most recent call last):
...
TypeError: conversion from Fraction to Decimal is not supported
``````

Right now I'm using this code:

``````>>> decimal.Decimal(float(fractions.Fraction(3, 10)))
Decimal('0.299999999999999988897769753748434595763683319091796875')
``````

Now, when I actually output this value, any amount of rounding will convert it to 0.3, and I only do this conversion immediately before output (all the core math is done with
`Fraction`
). Still, it seems a bit silly to me that I can't get a
`Decimal('0.3')`
from a
`Fraction(3, 10)`
. Any help would be appreciated!

How about leaving the division of the fraction to `Decimal()` itself?

``````def decimal_from_fraction(frac):
return frac.numerator / decimal.Decimal(frac.denominator)
``````

This is what `Fraction.__float__()` does (simply divide the numerator by the denominator), but by turning at least one of the two values into a `Decimal` object you get to control the output.

This lets you use the `decimal` context:

``````>>> decimal_from_fraction(fractions.Fraction(3, 10))
Decimal('0.3')
>>> decimal_from_fraction(fractions.Fraction(1, 55))
Decimal('0.01818181818181818181818181818')
>>> with decimal.localcontext() as ctx:
...    ctx.prec = 4
...    decimal_from_fraction(fractions.Fraction(1, 55))
...
Decimal('0.01818')
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download