Quick Answer: Python rounds 2.5 to 2 because it uses "banker's rounding" (round half to even), the standard rounding mode in IEEE 754. Unlike elementary school rounding that always rounds halves up, banker's rounding alternates rounding up and down to the nearest even number, eliminating systematic upward bias when summing large datasets.
Remember grade school arithmetic? The rule was simple: if a number ends in .5, you round up. Always.
So when you open a Python REPL, run round(2.5), and watch it evaluate to 2, your immediate instinct might be to file a bug report. But this is not a floating-point glitch, nor is it an off-by-one arithmetic error. It is a deliberate design choice with real statistical consequences.
Why does Python's round() function round down on 2.5?
Python does not actually round "down" on 2.5; it rounds to the nearest even integer. Because 2 is even and 3 is odd, round(2.5) resolves down to 2, whereas round(3.5) resolves up to 4.
This behavior applies across all half-integers in Python:
print(round(1.5)) # Output: 2
print(round(2.5)) # Output: 2
print(round(3.5)) # Output: 4
print(round(4.5)) # Output: 4
Notice the pattern: halves alternate between rounding up and rounding down depending on which neighboring integer is even. This strategy is known formally as round-half-to-even, or colloquially as banker's rounding.
What is banker's rounding and why does Python use it?
Banker's rounding is an algorithm designed to prevent positive statistical drift in calculations. When an algorithm always rounds halfway values up, it introduces an asymmetric bias that inflates aggregations over time.
Let's look at an example. Imagine your team processes a stream of midpoint values: 0.5, 1.5, 2.5, through 9.5. The true sum of these ten numbers is exactly 50.
If you apply the grade-school method (round half up) to each value before calculating the total, every single midpoint increments. Your sum becomes 55. That represents a 10% upward distortion introduced solely by the rounding rule.
With banker's rounding, half of the midpoints round up and half round down. The rounding errors cancel each other out, preserving the true sum of 50.
| Value | School Rounding (Half Up) | Banker's Rounding (Half to Even) |
|---|---|---|
| 0.5 | 1 | 0 |
| 1.5 | 2 | 2 |
| 2.5 | 3 | 2 |
| 3.5 | 4 | 4 |
| 4.5 | 5 | 4 |
| 5.5 | 6 | 6 |
| 6.5 | 7 | 6 |
| 7.5 | 8 | 8 |
| 8.5 | 9 | 8 |
| 9.5 | 10 | 10 |
| Sum | 55 (Biased) | 50 (Accurate) |
For banking, data science, and physics simulations where millions of operations compound, that systemic upward creep would lead to severe calculation errors.
How can you get standard "round half up" behavior in Python?
To achieve traditional school rounding where halves always round up, use Python's standard decimal module with the ROUND_HALF_UP context. The built-in round() function hardcodes the round-half-to-even rule and cannot be configured.
Here is how to force traditional rounding:
from decimal import Decimal, ROUND_HALF_UP
def round_half_up(val):
return int(Decimal(str(val)).quantize(Decimal('1'), rounding=ROUND_HALF_UP))
print(round_half_up(2.5)) # Output: 3
print(round_half_up(3.5)) # Output: 4
Always pass values as strings into Decimal to avoid pre-existing binary floating-point representation inaccuracies before the rounding takes place.
Frequently Asked Questions
Did Python 2 behave differently with round()?
Yes. Python 2 used round-half-away-from-zero for its built-in round() function, meaning round(2.5) yielded 3.0. Python 3 intentionally changed this behavior to adopt the IEEE 754 standard for floating-point arithmetic.
Does banker's rounding apply to negative numbers?
Yes, banker's rounding applies symmetrically to negative numbers. It rounds to the nearest even integer regardless of the sign. For example, round(-2.5) returns -2, while round(-3.5) returns -4.
Do other programming languages use banker's rounding?
Yes. Banker's rounding is widely used across languages and frameworks that adhere to IEEE 754 or process financial transactions, including C# (Math.Round), R, and modern implementations in Java and C++.
Top comments (0)