Python rounding issue and how to fix it
Consider the following piece of code:
print(f"3.625 -> {round(3.625, 2)}") print(f"3.635 -> {round(3.635, 2)}") print(f"3.645 -> {round(3.645, 2)}") print(f"3.655 -> {round(3.655, 2)}") print(f"3.665 -> {round(3.665, 2)}")
The code above produces the following output:
3.625 -> 3.62 3.635 -> 3.63 3.645 -> 3.65 3.655 -> 3.65 3.665 -> 3.67
Strange, isn’t it? The values which end with “5” should be rounded up! This is a common issue, because the float number which is stored as binary, is not represented exactly the same as in decimals. This is the source of the issue.
Thankfully, there is a simple way to fix this. Take a look at this function and the code:
import math def round_with_half_up(number_to_round, decimals=0): multiply_by = 10 ** decimals return math.floor(number_to_round * multiply_by + 0.5) / multiply_by print(f"3.625 -> {round_with_half_up(3.625, 2)}") print(f"3.635 -> {round_with_half_up(3.635, 2)}") print(f"3.645 -> {round_with_half_up(3.645, 2)}") print(f"3.655 -> {round_with_half_up(3.655, 2)}") print(f"3.665 -> {round_with_half_up(3.665, 2)}")
Now, the result looks like expected:
3.625 -> 3.63 3.635 -> 3.64 3.645 -> 3.65 3.655 -> 3.66 3.665 -> 3.67
The above function works fine also for other numbers, not only for the ones that end with “5” 🙂