Banker's Rounding: Round Half to Even
Banker's rounding sends exact halves to the nearest even digit: 2.5 becomes 2, 3.5 becomes 4. Why it cuts bias and where Python, .NET and Excel differ.
Banker's Rounding: Round Half to Even
If you have ever typed round(2.5) in Python and got 2, you have encountered banker's rounding. This rule rounds a number exactly halfway between two candidates to the nearest even digit. 2.5 goes to 2, not 3. 3.5 goes to 4. It is the default in IEEE 754-2019 floating-point arithmetic, used by Python, .NET, and many statistical packages. It exists to eliminate the cumulative upward bias that happens when you sum many rounded figures.
The Rule, With Examples
Banker's rounding applies only to ties, values exactly halfway between two possible rounded results. The rule is simple: look at the digit you are rounding to. If the digit to its right is exactly 5 (followed by nothing but zeros), round to the nearest even digit in the place you are keeping. If the digit is odd, round up; if even, leave it.
Examples for rounding to the nearest integer:
- 2.5 → 2 (2 is even)
- 3.5 → 4 (4 is even)
- 1.5 → 2 (2 is even)
- 4.5 → 4 (4 is even)
- 2.51 → 3 (not a tie)
- 3.49 → 3 (not a tie)
- 2.25 → 2.2 (2 is even)
- 2.35 → 2.4 (4 is even)
Why It Reduces Bias (Summing Many Rounded Values)
Alternating Tie Direction Cancels Error
The school method, round half up, always rounds ties upward. Over many numbers, that creates a systematic positive bias. Sum a dataset of 1000 values that are evenly distributed and round each one: the total will be higher than the sum of the original figures. Banker's rounding alternates the direction of the tie, so roughly half the ties round up and half round down. Over a large set, the bias cancels out.
Worked Example with Ten Ties
Consider ten values: 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5. The exact sum is 50.0.0. Using banker's rounding: 0 + 2 + 2 + 4 + 4 + 6 + 6 + 8 + 8 + 10 = 50, an overcount of 0.0.0. The half-up method overshoots by 10.0% of the true total. Banker's rounding overshoots by 0.0%.
| Original Number | Round Half-Up | Banker's Rounding | True Sum to Date |
|---|---|---|---|
| 0.5 | 1 | 0 | 0.5 |
| 1.5 | 2 | 2 | 3.5 |
| 2.5 | 3 | 2 | 6.0 |
| 3.5 | 4 | 4 | 10.0 |
| 4.5 | 5 | 4 | 14.0 |
| 5.5 | 6 | 6 | 19.5 |
| 6.5 | 7 | 6 | 25.5 |
| 7.5 | 8 | 8 | 33.0 |
| 8.5 | 9 | 8 | 41.0 |
| 9.5 | 10 | 10 | 50.0 |
Where It Is the Default (Python, .NET, IEEE 754)
Banker's rounding is not an exotic alternative, it is the default in three major systems you probably use.
Python round()
Python's built-in round() function uses round half to even. This has been documented since Python 3.0. If you need a different behavior, you must write it yourself. The failure case: financial calculations in Python will give different results than Excel unless you explicitly override.
.NET Math.Round()
Microsoft introduced a MidpointRounding enum with .NET 7. The default Math.Round() method uses MidpointRounding.ToEven. You can choose AwayFromZero, TowardZero, TowardPositive, or TowardNegative explicitly.
IEEE 754-2019
The IEEE 754-2019 standard defines five rounding-direction attributes in section 4.3. roundTiesToEven is the default for binary and decimal arithmetic. This is why many programming languages and hardware implementations use it.
| Tool / Language | Tie-Breaking Rule | Source |
|---|---|---|
| Python 3 (round()) | Half to even (banker's rounding) | Python 3 docs |
| .NET (Math.Round()) | Half to even (MidpointRounding.ToEven) | .NET 7 docs |
| IEEE 754-2019 | roundTiesToEven (default) | IEEE 754-2019 section 4.3 |
| JavaScript (Math.round()) | Half away from zero | ECMA-262 |
| Excel (ROUND) | Half away from zero | Microsoft Support |
| Google Sheets (ROUND) | Half away from zero | Google Sheets docs |
Where It Isn't (Excel ROUND, School Rounding)
Most people first learn rounding in school, where the rule is: if the digit is 5 or above, round up. This is round half up. For positive numbers, it is identical to half away from zero.5 to -2 (away from zero).
Excel's ROUND function uses half away from zero, not half up. The difference matters only for negative ties. Excel's ROUNDUP always rounds away from zero, and ROUNDDOWN always toward zero. MROUND also uses half away from zero.
The failure case: if you move financial data from Excel into Python, values ending in 5 may change. A value of 1.25 rounded to one decimal place gives 1.3 in Excel and 1.2 in Python. Always check which rule your tool uses before processing important data.
How to Get Half-Up Rounding When You Need It
In Python
Write a small function: add a tiny epsilon to bump the tie, then use round(). The standard trick is int(x + 0.5) for positive numbers, but that fails for negatives. A better approach: import decimal; from decimal import Decimal, ROUND_HALF_UP and use Decimal(str(x)).quantize(Decimal('1'), rounding=ROUND_HALF_UP). This works for any number but requires converting to string to avoid floating-point representation errors.
In .NET
Pass MidpointRounding.AwayFromZero to Math.Round(). For example: Math.Round(2.5, MidpointRounding.AwayFromZero) returns 3.
In Excel
You already have it. Excel's ROUND uses half away from zero. For half up, add a check for negative numbers: =IF(number<0, ROUNDUP(number, 0), ROUNDDOWN(number, 0)) for integers, but this gets complicated for decimal places. The simpler method: use ROUND and accept the away-from-zero behavior.
Test Every Tool in Your Pipeline
The single most practical thing you can do is to check the documentation of every tool in your pipeline before you rely on its rounding. Write a test: round 2.5 and 3.5. If 2.5 becomes 2, you have banker's rounding. If 2.5 becomes 3, you have half up or half away. If both become 3, you have half away from zero (since 3.5 rounds to 4 in both rules). A ten-second test can save you hours of debugging.
Common Questions
What is banker's rounding?
Banker's rounding, also called round half to even or convergent rounding, rounds a number exactly halfway between two candidates to the nearest even digit. It reduces cumulative upward bias in sums of rounded numbers.
Why does Python round 2.5 to 2?
Python's <code>round()</code> function uses banker's rounding. 2.5 is exactly halfway between 2 and 3; 2 is the nearest even digit, so the result is 2.
Is banker's rounding better than round half up?
It is better for statistical and scientific work where many numbers are rounded, because it cancels bias. For single values or financial calculations where a tie is rare, half up is fine.
Does Excel use banker's rounding?
No. Excel's <code>ROUND</code> function uses round half away from zero. For positive numbers this is the same as half up; for negative ties, -1.5 rounds to -2 in Excel but to -1 in half up.
How do I get round half up in Python?
Use the <code>decimal</code> module with <code>ROUND_HALF_UP</code>: <code>Decimal(str(x)).quantize(Decimal('1'), rounding=ROUND_HALF_UP)</code>. Avoid floating-point tricks with adding 0.5, as they fail for negative numbers and some ties.