leo-the-manic - 1 year ago 48

Python Question

In Python, the

`fractions.Fraction`

`decimal.Decimal`

`>>> 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`

`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`

`Decimal('0.3')`

`Fraction(3, 10)`

Answer Source

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')
```