Why does Python 3 round half to even?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Python 3 uses round-half-to-even, also called bankers' rounding, for its built-in round() behavior on ties. The reason is simple: when many values are rounded over time, always rounding .5 upward introduces bias, while half-to-even reduces that systematic drift.
What "half to even" means
When a value is exactly halfway between two representable rounded outcomes, Python chooses the one whose last kept digit is even.
Examples:
- '
round(1.5)becomes2' - '
round(2.5)becomes2' - '
round(3.5)becomes4' - '
round(4.5)becomes4'
The rule is not "round .5 down sometimes." The rule is "on exact ties, pick the even result."
Why Python chose this rule
If you always round halves upward, positive data tends to drift slightly upward after many operations. Half-to-even balances those ties across the number line and reduces aggregate bias.
That matters in statistics, accounting, simulation, and any workflow where thousands or millions of rounded values may be combined.
A single rounding operation may look surprising, but repeated rounding is where the design pays off.
Simple demonstration
Here is a short example showing Python's behavior.
If you expected every .5 to round away from zero, Python 3 will look unusual at first. But it is following a deliberate statistical rule.
This is separate from floating-point surprises
A very common confusion is blaming half-even rounding for results that are actually caused by binary floating-point representation.
For example:
Many people expect 2.68, but Python often prints 2.67. That is not because half-even is "wrong." It is because 2.675 cannot be represented exactly in binary floating-point, so the internal stored value is slightly below the decimal number you typed.
In other words, two separate ideas are in play:
- tie-breaking rule, which is half-to-even
- floating-point representation, which may mean the value is not an exact tie at all
Exact decimal rounding when you need it
If you need decimal-style rounding with precise control, use the decimal module.
This is especially useful for financial or reporting applications where decimal behavior must be explicit and reproducible.
Historical context
Python 3 adopted this behavior as part of a more principled numeric model. The idea was not to surprise users for fun; it was to use a rounding rule that better matches common numerical standards and reduces long-run error bias.
Many other languages, databases, and financial systems also use half-even in at least some of their numeric contexts.
When it matters in real code
For casual scripts, the difference is often small. But in data pipelines or simulations, the choice of tie-breaking rule can change aggregates noticeably over time.
That is why good numerical code does not assume "round means round halves up." It checks and documents the rounding rule being used.
Common Pitfalls
A common mistake is assuming every unexpected round() result is caused by half-even logic. Often the real culprit is floating-point representation.
Another issue is using binary floats for money-like values where decimal rounding requirements are strict. In those cases, use Decimal instead of float.
It is also easy to port code from another language or spreadsheet system and silently assume the rounding rules match. They may not.
Summary
- Python 3 uses round-half-to-even to reduce bias in repeated rounding.
- On exact
.5ties, it chooses the rounded result whose last kept digit is even. - This rule is different from floating-point representation issues.
- '
round(2.675, 2)is a float-representation example, not just a half-even example.' - Use
decimal.Decimalwhen you need exact decimal rounding behavior.

