Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 589
Dan Passaro Avatar asked Nov 07 '16 15:11

Dan Passaro


People also ask

What is the easiest way in converting a fraction to a decimal?

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.

How do you change a fraction into a decimal with an example?

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.

How do you turn 7/8 into a decimal?

7 divided by 8 or 7/8 is equal to 7 divided by 8, which is equal to 0.875.


1 Answers

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')
like image 97
Martijn Pieters Avatar answered Oct 24 '22 09:10

Martijn Pieters