I've been playing around with python for a bit now and i've noticed a strange behavior that makes me curious: what is the difference between float(int(n))
and round(n)
?
When should I use one, another or neither of them?
Note: The python implementation changed between 2.7 and 3.x. I corrected the answer accordingly.
For the sake of completeness, let me add two more functions to your question and explain the differences between float(int(x))
, math.floor(x)
, round(x)
and math.ceil(x)
.
Let's start with a question: "What integer represents best the number 1.6?" We have two possible answers (1 and 2) but many different reasons why one answer may be better than the other one:
int(1.6)==1
: This is what you get when you cut off the decimals.math.floor(1.6)==1
: It's less than 2. Incomplete pieces don't count.round(1.6)==2
: Because 2 is closer than 1.math.ceil(1.6)==2
: It's more than 1. When you start a part, you have to pay the full price.Let's ask python to print a nice table of the results you get with different values of x:
from math import floor, ceil
tab='\t'
print('x \tint\tfloor\tround\tceil')
for x in (
1.0, 1.1, 1.5, 1.9, -1.1, -1.5, -1.9,
-2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
):
print(x, int(x), floor(x), round(x), ceil(x), sep=tab)
Here is the output:
x int floor round ceil
1.0 1 1 1 1
1.1 1 1 1 2
1.5 1 1 2 2
1.9 1 1 2 2
-1.1 -1 -2 -1 -1
-1.5 -1 -2 -2 -1
-1.9 -1 -2 -2 -1
-2.5 -2 -3 -2 -2
-1.5 -1 -2 -2 -1
-0.5 0 -1 0 0
0.5 0 0 0 1
1.5 1 1 2 2
2.5 2 2 2 3
You see that none of these four functions are equivalent.
floor
rounds towards minus infinity: It chooses always the lowest possible answer: floor(1.99)==1
and floor(-1.01)==-2
.ceil
rounds towards infinity: It chooses always the highest possible answer: ceil(1.01)==2
and ceil(-1.99)=-1
.int
rounds towards zero: For positive x
it is like floor
, for negative x
it is like ceil
.round
rounds to the closest possible solution: round(1.49)=1
and round(1.51)==2
. When x
is exactly at the midpoint of two consecutive integers, round(x)
will be the closest even number.
round(1.5)==2
and round(2.5)==2
. This is called half to even rounding or Banker's Rounding because it is commonly used in financial calculations.Note: The python implementation changed between 2.7 and 3.x: Python 2.7 does not use the "half-to-even rounding" rule (explained above) but rounds all half-numbers away from zero: round(1.5)==2
and round(-1.5)==-2
. Bankers and mathematicians who care about this agree that the "half to even rounding" rule used in 3.x is the "right way" to do it because it distributes rounding errors fairly.