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!
The easiest way to convert a fraction to a decimal is to divide the numerator (the top of the fraction) by the denominator (the bottom of the fraction) by using a calculator. The resulting answer will be the value of the fraction expressed as a decimal number.
The fraction 1/4 becomes 1 ÷ 4. Complete the division to convert the fraction to a decimal. You can reduce the fraction to lowest terms first to make the long division math a bit easier. For example, 9/12 = 9 ÷ 12 = 0.75.
7 divided by 8 or 7/8 is equal to 7 divided by 8, which is equal to 0.875.
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')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With