views:

209

answers:

1

The // "integer division" operator of Python surprised me, today:

>>> math.floor(11/1.1)
10.0
>>> 11//1.1
9.0

The documentation reads "(floored) quotient of x and y". So, why is math.floor(11/1.1) equal to 10, but 11//1.1 equal to 9?

+1  A: 

Because 1.1 can't be represented in binary form exactly; the approximation is a littler higher than 1.1 - therefore the division result is a bit too small.

Try the following:

Under Python 2, type at the console:

>>> 1.1
1.1000000000000001

In Python 3.1, the console will display 1.1, but internally, it's still the same number.

But:

>>> 11/1.1
10.0

As gnibbler points out, this is the result of "internal rounding" within the available precision limits of floats. And as The MYYN points out in his comment, // uses a different algorithm to calculate the floor division result than math.floor() in order to preserve a == (a//b)*b + a%b as well as possible.

Use the Decimal type if you need this precision.

Tim Pietzcker
But according to Python `11.0/1.1 == 10.0` is true
sth
As we know 1.1 is stored as 1.1000000000000001, so the result 11.0/1.1 in Python is 9.999999999999999090909090909 but the closest float to this number is infact 10.0, so it happens that the result is exactly 10.0
gnibbler
@Tim I thought of that, and I believe this is the key to the difference between math.floor(11/1.1) and 11//1.1. However, as gnibbler pointed out, the fact that 1.1 is represented by a slightly larger number only indicates that math.floor(11/1.1) should really be 9.0, which leaves the original question still open.
EOL
@EOL, since 11/1.1 evaluates to exactly 10.0, math.floor(11/1.1)=math.floor(10.0), however this is only due to some luck with the rounding
gnibbler
@gnibbler: Yeah, it's the "luck" aspect that surprised me: two "identical" operations behaving in a different way. :) The explanation is in the implementation, as pointed out by The MYYN.
EOL