How to Round Numbers in Python

In the previous post, we used Python’s standard library decimal module for applications that require high precision. We also saw examples showing how changing the desired precision through the context object affects the results.

However, setting the number of significant digits is necessary, but usually not sufficient to achieve the desired accuracy. To complete the picture, we also need to define a rounding strategy, since numbers can be rounded according to several different rules or principles.

Let’s consider a practical example. Suppose a company wants to calculate its gross consumer prices in euros, rounded to two decimal places. When multiplying net prices by the VAT rate, the result may have more than two decimal digits. The question then arises: how should the values be rounded?

  • Companies typically round prices up, so they would use a “round up” method.
  • A strict teacher calculating grade averages, or a budget-conscious manager approving bonuses, might instead prefer to round down consistently.
  • Financial analysts, on the other hand, aim for the most accurate overall results when producing reports from large datasets. They often use a different rounding strategy — commonly known as banker’s rounding — which minimizes cumulative rounding error when applied to large sets of numbers.

The decimal module supports not only these rounding methods, but several others as well. To use them, you simply assign one of the module constants expressing a particular rounding mode (listed below) to the rounding attribute of the current context object. The constant names correspond to their widely accepted English terminology.

Each of these rounding approaches determines how the result of a decimal operation is rounded to match the current precision, based on specific rounding rules:

  • ROUND_UP – Always rounds away from zero.
  • ROUND_DOWN – Also known as truncation; always rounds toward zero.
  • ROUND_CEILING – Always rounds toward positive infinity.
  • ROUND_FLOOR – Always rounds toward negative infinity.
  • ROUND_HALF_UP – If the first discarded digit is less than 5, round down; if it is 5 or greater, round up.
  • ROUND_HALF_DOWN – Rounds to the nearest number, with ties (where the discarded digit is exactly 5 followed by zeros) being rounded toward zero.
  • ROUND_HALF_EVEN – Also known as banker’s rounding. If the first discarded digit is less than 5, round down; greater than 5, round up; if exactly 5 followed by non-zero digits, round up; if 5 followed only by zeros, round so that the final digit is even.
  • ROUND_05UP – Like ROUND_DOWN, except when the rounding would leave the last digit as 0 or 5—in that case, round up.

The program below demonstrates how each rounding strategy affects the result:

Understanding the logic and the appropriate use of these rounding strategies can be challenging. That is why the e-book Python Knowledge Building Step by Step devotes an entire subchapter to this topic. It explains the principles behind each method using figures and example programs to make the concepts easy to grasp.

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