# Python fractions module

As we know, a fraction is a number which represents a whole number being divided into multiple parts. Python fractions module allows us to manage fractions in our Python programs.

## Managing fractions

In this Python post, we will manage fractions and perform various operations on them. Let’s get started.

### Creating Fractions

Fraction class in Python allows us to make its instance in various ways. Here is a sample program:

1 2 3 4 5 6 |
import fractions for num, decimal in [(3, 2), (2, 5), (30, 4)]: fract = fractions.Fraction(num, decimal) print('{}/{} = {}'.format(num, decimal, fract)) |

Let’s see the output for this program:

This means that we can easily convert a fraction into a String and manage it to debug in our prograns. Also, notice that in the last fraction `30/4`

, it was automatically resolved to the lowest form as `15/2`

.

We can also create a fraction from its String representation actually, like:

1 2 3 |
f = fractions.Fraction('2/7') |

### Converting Decimals to Fractions

It is also possible to convert a decimal into a Fractional number. Let’s look at a code snippet:

1 2 3 4 5 6 |
import fractions for deci in ['0.6', '2.5', '2.3', '4e-1']: fract = fractions.Fraction(deci) print('{0:>4} = {1}'.format(deci, fract)) |

Let’s see the output for this program:

Pretty easy to manage, right? But here is a catch, decimal values which cannot be exactly turned into a fraction might yield unexpected results like:

1 2 3 4 5 |
import fractions for v in [0.1, 0.5, 1.5, 2.0]: print('{} = {}'.format(v, fractions.Fraction(v))) |

This will give an output as:

Noticed the issue with `0.1`

representation? Let’s understand why this happens.

### Issue with 0.1 representation

As we clearly know, floats consist of two parts, an integer and an exponent part of which the base is taken to and multiplied by the integer part.

`Base 10`

makes working with math very easy as with Base 10, every number can be presented very easily. `0.5`

can be represented as `5 x 10?¹`

. So, if we add numbers like 0.5 and 0.2, the result will be 0.7. But, the computers don’t work that way. **Computers use Base 2** and not Base 10.

The issue arises with numbers which can be represented by Base 10 but not Base 2. Those numbers have to be rounded off to their closest equivalent. Considering the IEEE 64-bit floating point format, the closest number to 0.1 is `3602879701896397 x 2???`

, and the closest number to 0.2 is `7205759403792794 x 2???`

; adding them gives `10808639105689191 x 2???`

, or an exact decimal value of `0.3000000000000000444089209850062616169452667236328125`

. **Floating point numbers are generally rounded for display.**

## Arithmetic Operations

We can also perform Arithmetic Operations quite easily with fractional numbers. Let’s see some examples here.

### Performing Mathematical operations

Let’s construct a simple example that shows how to perform arithmetic operations with fractional numbers. Here is a sample program:

1 2 3 4 5 6 7 8 9 |
import fractions f_one = fractions.Fraction(3, 5) f_two = fractions.Fraction(4, 9) print('{} + {} = {}'.format(f_one, f_two, f_one + f_two)) print('{} - {} = {}'.format(f_one, f_two, f_one - f_two)) print('{} * {} = {}'.format(f_one, f_two, f_one * f_two)) print('{} / {} = {}'.format(f_one, f_two, f_one / f_two)) |

Let’s see the output for this program:

### Getting parts of fractions

It is possible to get only the numerator or the denominator of a fraction. Let’s look at a code snippet on how this can be done:

1 2 3 4 5 6 |
import fractions fract = fractions.Fraction(221, 234) + fractions.Fraction(1, 2) print("Numerator: {}".format(fract.numerator)) print("Denominator: {}".format(fract.denominator)) |

Let’s see the output for this program:

### Making Approximations

We can use the fractions module to approximate and round off a number to a rational value. Here is a sample program:

1 2 3 4 5 6 7 8 9 10 |
import fractions import math print('Value of PI: {}'.format(math.pi)) pi_fraction = fractions.Fraction(str(math.pi)) print('Without limit: {}'.format(pi_fraction)) for num in [1, 6, 11, 60, 70, 90, 100]: limited = pi_fraction.limit_denominator(num) print('{0:8} = {1}'.format(num, limited)) |

Let’s see the output for this program:

The `limit_denominator()`

function finds and returns the closest fraction that has the denominator with maximum value of `num`

passed to it.

### Rounding off fractions

It is possible to round off fractions by the number of digits we want in the denominator. Let’s look at a code snippet:

1 2 3 4 5 6 7 |
import fractions fract = fractions.Fraction('25/3') print('25/3 Rounded without limit : {}'.format(round(fract))) print('25/3 Rounded to 1 digit : {}'.format(round(fract, 1))) print('25/3 Rounded to 2 digits : {}'.format(round(fract, 2))) |

Let’s see the output for this program:

Note that `round()`

is a default Python’s interpreter function and doesn’t want any imports.

### Mixing Math with Fractions

In a final example, we will bring some functions from math library and mix them with fractional representations here. Like flooring a fraction etc. Let’s look at a code snippet:

1 2 3 4 5 6 7 8 9 |
import math from fractions import Fraction print("25/2 Square root is: {}".format(math.sqrt(Fraction(25, 4)))) print("28/3 Square root is: {}".format(math.sqrt(Fraction(28,3)))) print("4102/1193 Floored to: {}".format(math.floor(Fraction(4102, 1193)))) print("Pi/3 Sined Fraction: {}".format(Fraction(math.sin(math.pi/3)))) print("Pi/3 Sined Fraction Limit Dn.: {}".format(Fraction(math.sin(math.pi/3)).limit_denominator(10))) |

Let’s see the output for this program:

The floor() function just rounds of a decimal equivalent and provides the nearest integer.

## Conclusion

In this lesson, we studied how we can manage and use Fraction values in our Python program effectively.

Reference: API Doc