When performing various arithmetic operations, it is important that the result be rounded correctly. Often it is necessary to round up, round down, round to the nearest whole number, or round to the nearest hundredth. For that, the programmer can use different tools, such as the built-in round() function, conversion to int type, and functions from the math plugin.
Ways to round numbers
There are a lot of ways to round numbers; they are not without disadvantages, but are often used to solve problems. Let’s go over the intricacies of each method. If you use the standard math library, you first connect it to your code. You can do that with, for example, the following instruction:
math.ceil() – rounding numbers up
This function gets its name from the term “ceiling”, which is used in mathematics to describe a number that is greater than or equal to a given number. Any fraction is in an integer range, e.g. 1.2 is between 1 and 2. The
ceil() function determines which of the limits of the interval is the largest and writes it in the result of rounding. Example:
math.ceil(5.15) # = 6 math.ceil(6.666) # = 7 math.ceil(5) # = 5
math.floor() – rounding numbers down
The function rounds a fractional number to the nearest whole number that is less than or equal to the original number. Works similarly to
ceil(), but with rounding in the opposite direction. Example:
math.floor(7.9) # = 7 math.floor(9.999) # = 9 math.floor(-6.1) # = -7
math.trunc() – discarding the fractional part
Returns a whole number without considering the fractional part. That is, there is no rounding; Python simply forgets about the fractional part, bringing the number to integer form. Examples:
math.trunc(5.51) # = 5 math.trunc(-6.99) # = -6
You can get rid of the fractional part by simply converting the number to the int type. This is fully equivalent to using
int(5.51) # = 5 int(-6.99) # = -6
Python allows you to implement normal arithmetic rounding using the int conversion function. Although
int() works a different algorithm, the result of using it for positive numbers is exactly the same as the output of floor(), which rounds numbers “down”. For negative numbers, it is similar to ceil(). Examples:
math.floor(9.999) # = 9 int(9.999) # = 9 math.ceil(-9.999) # = -9 int(-9.999) # = -9
To round a number using the int() function, you must add 0.5 to it if it is positive, and -0.5 if it is negative. Then the operation looks like this: int(num + (0.5 if num > 0 else -0.5)). To avoid writing the condition every time, it is convenient to make a separate function:
def int_r(num): num = int(num + (0.5 if num > 0 else -0.5)) return num
The function works the same way as the standard rounding function in the second version of Python (arithmetic rounding). Examples:
int_r(11.5) # = 12 int_r(11.4) # = 11 int_r(-0.991) # = -1 int_r(1.391) # = 1
round() – rounding of numbers
round() is a standard rounding function in Python. It does not always work as expected, and its algorithm differs in different versions of Python.
In Python 2
The second version of Python uses arithmetic rounding. It has an ever-increasing margin of error, which leads to inaccuracies and errors. The increase in error is caused by an unequal number of digits determining which way to round. Only 4 digits on the end result in “down” rounding, and 5 digits in “up” rounding. There can also be inaccuracies, for example if you round 2.675 to the second digit you get 2.67 instead of 2.68. This is because decimal ‘float’ numbers cannot be represented accurately in binary code.
In Python 3
The third version of Python uses bank rounding. This means that rounding is done to the closest even number. This approach does not get rid of errors completely, but it reduces the chance of errors occurring and allows the programmer to achieve greater accuracy in calculations. Examples:
round(3.5) # = 4 round(9.5) # = 10 round(6.5) # = 6 round(-6.5) # = -6 round(-7.5) # = -8
But if you need rounding like in Python 2 for some reason, you can use the function we wrote above based on integer rounding.
Rounding to a hundredth
raund() function has another argument. It tells us how many decimal places to round to. So, if we want to round to hundredths in Python, we should set this argument to 2. Here’s an example of rounding to the right decimal place:
round(3.555, 2) # = 3.56 round(9.515,1) # = 9.5 round(6.657,2) # = 6.66
Rounding errors and the decimal module
When rounding with round(), you can get the following:
round(2.65, 1) # = 2.6 round(2.85, 1) # = 2.9
Why is it rounded down in one case and up in the other? Translating 2.85 into binary produces a number that is slightly larger. So the function sees “>5” instead of “5” and rounds up. The problem of inaccurate number representation is nicely illustrated by an example:
print (0.1 + 0.1 + 0.1) 0.30000000000000004
Because of such errors, numbers of the “float” type cannot be used where changing a value by one-thousandth can give wrong results. The decimal module can help to solve this problem.