Short Answer
When you call round(2.5) in Python, you might expect 3 based on the common “round half up” rule taught in many classrooms. Instead, Python returns 2. This behavior, known as banker’s rounding or round half to even, is not a quirk but a deliberate design choice rooted in statistical accuracy and international standards. This article, part of our precision and rounding reference, explains why Python adopts this convention, how it aligns with metrology standards, and what it means for your calculations.
Rule Statement
Banker’s rounding is a tie-breaking rule for rounding numbers exactly halfway between two possible rounded values. The rule states: when the fractional part is exactly 0.5, round to the nearest even digit. For example:
round(2.5)→2(2 is even)round(3.5)→4(4 is even)round(1.25, 1)→1.2(2 is even)round(1.35, 1)→1.4(4 is even)
This rule applies to both positive and negative numbers. For negative numbers, the same logic applies to the absolute value: round(-2.5) → -2 because 2 is even, and round(-3.5) → -4 because 4 is even.
The rationale is to avoid the systematic upward bias introduced by the more common “round half up” rule. In a large dataset with many ties, half-up rounding consistently increases the average, whereas half-even rounding distributes ties evenly between even and odd results, keeping the statistical expectation unbiased.
Worked Examples
Let’s walk through several examples to see how banker’s rounding works in practice, including cases with a specified number of decimal places.
Example 1: Rounding to the Nearest Integer
round(2.5)– The fractional part is exactly 0.5. The two nearest integers are 2 and 3. Since 2 is even, the result is 2.round(3.5)– The two nearest integers are 3 and 4. Since 4 is even, the result is 4.round(4.5)– The two nearest integers are 4 and 5. Since 4 is even, the result is 4.round(5.5)– The two nearest integers are 5 and 6. Since 6 is even, the result is 6.
Example 2: Rounding to a Specified Number of Decimal Places
When the second argument ndigits is provided, the same rule applies to the digit at that position.
round(1.25, 1)– The digit in the tenths place is 2, and the next digit is 5 (exactly halfway). The two possible results are 1.2 and 1.3. Since 2 is even, the result is 1.2.round(1.35, 1)– The digit in the tenths place is 3, and the next digit is 5. The two possible results are 1.3 and 1.4. Since 4 is even, the result is 1.4.round(2.675, 2)– This is a classic pitfall. Due to binary floating-point representation,2.675is actually stored as2.6749999999999998, so the result is 2.67, not 2.68. This is not a banker’s rounding issue but a floating-point precision artifact.
Counter-Examples
Understanding what banker’s rounding is not helps clarify its behavior. Here are common misconceptions and counter-examples:
- Counter-example 1:
round(2.5)does not return 3. Many expect half-up rounding, but Python returns 2. - Counter-example 2:
round(1.25, 1)does not return 1.3. It returns 1.2 because 2 is even. - Counter-example 3:
round(-2.5)does not return -3. It returns -2, following the same even-digit rule. - Counter-example 4:
round(0.5)returns 0, not 1, because 0 is even.
These examples highlight that banker’s rounding is not symmetric in the way half-up is; it is symmetric in terms of bias reduction, not in terms of always rounding away from zero.
Convention Comparison Table
The table below compares the most common rounding methods for a set of tie values. The “tie” column indicates numbers exactly halfway between two rounding candidates.
| Value | Half-Up | Half-Down | Half-Even (Banker’s) | Half-Odd |
|---|---|---|---|---|
| 2.5 | 3 | 2 | 2 | 3 |
| 3.5 | 4 | 3 | 4 | 3 |
| 4.5 | 5 | 4 | 4 | 5 |
| 5.5 | 6 | 5 | 6 | 5 |
| -2.5 | -3 | -2 | -2 | -3 |
| -3.5 | -4 | -3 | -4 | -3 |
As seen, half-even rounding produces a mix of even and odd results, whereas half-up always rounds away from zero (for positive numbers) and half-down always rounds toward zero. The half-even method minimizes cumulative error in sums and averages.
Standards Citation
Banker’s rounding is not an arbitrary choice; it is endorsed by several international standards and metrology guidelines.
- IEEE 754 (Standard for Floating-Point Arithmetic) specifies round-to-nearest-even as the default rounding mode for binary floating-point operations. Python’s
round()for floats follows this standard. - ISO 80000-1:2009 (Quantities and units – Part 1: General) clause 7.3.4 recommends rounding to the nearest even digit when the discarded digit is exactly 5, to avoid systematic bias in statistical data.
- NIST SP 811 (Guide for the Use of the International System of Units) section 7.2.2 discusses rounding rules and notes that “round half to even” is preferred for reducing rounding errors in calculations.
- GUM (JCGM 100:2008) – Evaluation of measurement data – Guide to the expression of uncertainty in measurement, clause 7.2.6, advises using a rounding rule that does not introduce bias, implicitly supporting half-even.
These standards are used in scientific, engineering, and financial contexts to ensure that rounding does not distort results, especially when many numbers are rounded in a series.
Common Mistakes
Even experienced programmers and scientists can fall into traps when using round(). Here are the most frequent errors:
- Assuming half-up rounding: Many expect
round(2.5)to be 3. Always verify the tie-breaking rule in your language or tool. - Ignoring floating-point representation: Numbers like
2.675are not stored exactly. The result ofround(2.675, 2)is 2.67, not 2.68, due to binary approximation, not the rounding rule. - Using
round()for financial calculations: For currency, use thedecimalmodule with an explicit rounding mode (e.g.,ROUND_HALF_UP) to match legal or accounting requirements. - Confusing
round()withint()orfloor():int(2.5)truncates to 2, butround(2.5)also gives 2, which can mask the difference. For negative numbers,int(-2.5)gives -2, whileround(-2.5)also gives -2, but for other values they diverge. - Not considering the second argument:
round(2.5)andround(2.5, 0)are equivalent, butround(2.5, 1)would round to 2.5 (no tie).
Software Behavior Note
Python is not alone in using banker’s rounding. Many programming languages and tools adopt this convention for floating-point operations:
- Python:
round()uses round half to even for floats and for thedecimalmodule whenROUND_HALF_EVENis set (the default). - JavaScript:
Math.round()uses half-up for positive numbers and half-down for negative numbers (i.e., it rounds toward +∞). This is different from Python. - Java:
Math.round()uses half-up (rounds toward positive infinity for ties). However,BigDecimalallows explicit rounding modes. - C/C++: The
round()function in the standard library uses half-away-from-zero, butrint()andnearbyint()use the current rounding mode, which defaults to round-to-nearest-even. - Excel:
ROUND()uses half-up, whileROUNDHALFEVEN()is available in some versions.
This inconsistency across software is a common source of confusion. Always check the documentation for the specific language or tool you are using.
Quick Reference Table
Here is a quick reference for common round() calls in Python and their results:
| Expression | Result | Explanation |
|---|---|---|
round(2.5) |
2 | 2 is even |
round(3.5) |
4 | 4 is even |
round(4.5) |
4 | 4 is even |
round(5.5) |
6 | 6 is even |
round(1.25, 1) |
1.2 | 2 is even |
round(1.35, 1) |
1.4 | 4 is even |
round(-2.5) |
-2 | 2 is even |
round(-3.5) |
-4 | 4 is even |
Sources & Further Reading
For deeper understanding, consult the following authoritative resources:
- Python Documentation: Built-in Functions – round()
- IEEE 754-2019: Standard for Floating-Point Arithmetic
- ISO 80000-1:2009: Quantities and units – Part 1: General
- NIST SP 811: Guide for the Use of the International System of Units (SI)
- JCGM 100:2008: Evaluation of measurement data – Guide to the expression of uncertainty in measurement (GUM)
These references provide the formal basis for rounding conventions and are essential for anyone working in metrology, data science, or scientific computing.
FAQ
Why does Python's round() use banker's rounding?
Python follows the IEEE 754 standard for floating-point arithmetic, which specifies round-to-nearest-even as the default rounding mode. This reduces cumulative bias in statistical calculations and is recommended by metrology standards like ISO 80000-1.
How can I get half-up rounding in Python?
For decimal numbers, use the decimal module with ROUND_HALF_UP. For floats, you can implement a custom function, but beware of floating-point representation issues. Example: def round_half_up(x, ndigits=0): import decimal; d = decimal.Decimal(x); return float(d.quantize(decimal.Decimal('1e-'+str(ndigits)), rounding=decimal.ROUND_HALF_UP)).
Does banker's rounding affect significant figures?
Yes. When rounding to a certain number of significant figures, the same tie-breaking rule applies. For instance, rounding 2.55 to two significant figures gives 2.6 (since 6 is even) under half-even, but 2.5 under half-up. This can lead to different results in scientific calculations.
Leave a Reply