# Fun with Python fractions One of the most under-appreciated packages in Python is the `fractions` package. I already mentioned in this blog that floating points are a good way to shoot yourself in the foot, and rational fractions is often the saner alternative.

Basically this package offers a `Fraction` class that represents a rational number with two integers, a numerator and a denominator, like you learnt in school.

```a = fractions.Fraction(1, 3)
a → Fraction(1, 3)
str(a) → ⅓
float(a) → 0.3333333333333333
a * 3 → Fraction(1, 1)
a * 3 == 1 → True
a + 3 → Fraction(10, 3)
```

So far, so good. Now what happens when you convert a float into a fraction.

```b = fractions.Fraction(0.3)
b → Fraction(5404319552844595, 18014398509481984)
```

What happened here? The fraction representing 0.3 should be `fractions.Fraction(3, 10)`! This is the floating point representation roaring its head, the fraction does not represent 0.3, but the floating point representation of 0.3. That conversion is actually exact. Let’s dig a bit more.

```hex(b.numerator) → '0x13333333333333'
hex(b.denominator) → '0x40000000000000'
c = fractions.Fraction(3, 10) - b
c → Fraction(1, 90071992547409920)
hex(c.denominator) → '0x140000000000000'
```

But you can force a more compact representation using the `limit_denominator` method.

```fractions.Fraction(0.3).limit_denominator(100) → Fraction(3, 10)
```

Now, of course, you can’t convert all floating point values to fractions.

```fractions.Fraction(float('Inf'))
→ OverflowError: cannot convert Infinity to integer ratio
```

This site uses Akismet to reduce spam. Learn how your comment data is processed.