In Python 2 rounding is done away from 0
, so, for example, round(0.5)
is 1.0
.
In Python 3.x, however, rounding is done toward the even choice, so round(0.5)
is 0
.
What function can I use in Python 3.x to get the old behavior?

- 16,572
- 3
- 28
- 55

- 14,248
- 20
- 86
- 160
-
2Do you really want the Python 2 rounding behaviour? The behaviour is pretty complex https://stackoverflow.com/a/22155830/6260170 – Chris_Rands Aug 07 '18 at 12:52
-
You should make clear that you're referring only to rounding of values ending in `.5`. – interjay Aug 07 '18 at 12:54
9 Answers
If your code is not particularly performance sensitive, you can use the standard decimal
library to achieve the result you want. Decimal().quantize()
allows choosing the rounding method:
from decimal import Decimal, ROUND_HALF_UP
result = float(Decimal(0.5).quantize(Decimal(0), rounding=ROUND_HALF_UP))
print(result) # Will output 1.0

- 1,705
- 11
- 15
Equivalent of Python 2.7 round()
when rounding to an integer (one-parameter):
import math
def py2round(x):
if x >= 0.0:
return math.floor(x + 0.5)
else:
return math.ceil(x - 0.5)

- 8,025
- 2
- 27
- 45
To get the Python 2 rounding behavior in Python 3 for the one-argument form of round()
you can use a custom function like this:
def myround(n):
if round(n + 1) - round(n) == 1:
return float(round(n))
return n + abs(n) / n * 0.5
Demo:
>>> myround(0.5)
1.0
>>> myround(1.5)
2.0
>>> myround(-0.5)
-1.0
>>> myround(-1.5)
-2.0
>>> myround(1)
1.0

- 142,882
- 41
- 325
- 378
def round_up(x):
aX = abs(x)
return math.ceil(aX)*(aX/x)
This solution might work for you.
For x = -1.2 round_up(x) = -2
, x = 2.3 round_up(x) = 3
etc.
edit: this solution will crash for x = 0. you can change the return value to
return math.ceil(aX)*(aX/x) if x is not 0 else 0

- 542
- 1
- 5
- 16
According to CPython source code,
The basic idea is very simple: convert and round the double to a decimal string using _Py_dg_dtoa, then convert that decimal string back to a double with _Py_dg_strtod. There's one minor difficulty: Python 2.x expects round to do round-half-away-from-zero, while _Py_dg_dtoa does round-half-to-even. So we need some way to detect and correct the halfway cases.
If you care about the performance, consider copying the relevant C code and import as an extension. But if you don't care, here's a Python implementation:
def myround(a):
num = str(a)
num = str.split('.', 1)
if int(num[1][0]) >= 5:
return int(num[0]) + 1 if a > 0 else int(num[0]) - 1
else:
return int(num[0]) - 1 if a > 0 else int(num[0]) + 1

- 1,752
- 1
- 18
- 33
Pretty much like the other solutions, but using a shorthand if statement instead of a function:
segments = ceil(gamma / 90) if gamma > 0 else floor(gamma/90)

- 1,265
- 12
- 21
I use this:
f = lambda i:i-i%(1|-(i>0))
print(f('your float number'))
hope be useful!

- 3
- 4
-
1This looks like it rounds to the nearest infinity, not to the nearest whole like python 2 does it, the question was specifically concerned about the beheaviour with `.5`. You can also provide more context on how exactly the function does the rounding. – Numerlor Feb 04 '22 at 18:44
For positive numbers the following works for me:
>>> import math
>>> x = 0.5
>>> (math.trunc(x*2)+1) >> 1
1

- 336
- 2
- 9
This is a possible solution I've come up with:
import math
def round_away_from_zero(x):
a = abs(x)
r = math.floor(a) + math.floor(2 * (a % 1))
return r if x >= 0 else -r
Tests:
round_away_from_zero(0.5)
# 1
round_away_from_zero(1.5)
# 2
round_away_from_zero(2.5)
# 3
round_away_from_zero(-0.5)
# -1
round_away_from_zero(-1.5)
# -2
round_away_from_zero(-2.5)
# -3

- 58,456
- 7
- 77
- 121