When and Why Should You Use Fractions in Calculations?

In earlier posts, we discussed how the decimal module can help mitigate the precision limitations inherent in Python’s float type.

However, even the Decimal type cannot provide infinite precision. This can be problematic when working with rational numbers—those that can be expressed as the quotient of two integers—if their decimal representation is infinitely repeating. In such cases, it can be particularly useful to work with common fractions.

Common fractions are defined by a numerator and a denominator and can be created using the Fraction type from the standard library’s fractions module.

Representing infinite decimals with the float type can not only lead to precision issues but also cause subtle runtime errors that can be difficult to detect and fix. By using fractions ( Fractionobjects), such issues can often be resolved.

Let’s illustrate this with an example.

Imagine a scenario—such as a wedding—where a cake of a given weight must be divided precisely among guests. To model this, we assume that each slice’s weight is calculated as a fixed ratio of the original total cake weight.

Here’s a simple function that models this process:

The first argument of the function specifies the total cake weight in grams.

The second argument represents the share ratio, which is the reciprocal of the number of guests.

Inside the function, we repeatedly subtract a slice from the remaining cake until nothing is left. Since we know that floating-point arithmetic doesn’t always produce an exact zero, we stop the loop when the remaining amount is sufficiently close enough to zero, based on a chosen tolerance value.

For verification, the function returns both the sum of all slice weights and the remaining cake weight. As we can see from the test results, using Fraction produces exact values, whereas using float does not.

One might think we could improve accuracy simply by tightening the loop’s tolerance condition — say, changing it from 1e-11 to 1e-12 or smaller. But if we try that, the program enters an infinite loop.

That’s because the results of repeated subtractions stop changing after a certain point—the difference never becomes smaller than a specific minimum, which itself depends on the initial cake weight. So if the cake’s weight changes, a tolerance value that once worked might suddenly fail.

In this case, the only reliable and accurate solution is to use the Fraction type. The details of working with Fraction objects, along with additional interesting use cases—such as computing continued fractions—are covered in a dedicated chapter of the e-book Python Knowledge Building Step by Step.

Interested in the e-book Python Knowledge Building Step by Step: From the Basics to Your First Desktop Application?