>>> print (12//0.2)
59.0
>>> print(floor(12/0.2))
60
Why floor division is not working according to the rule in this case?
p.s. Here Python is treating 0.2
as 0.20000000001
in the floor division
case
So
(12/0.2000000001)
is resulting in 59.999999...
And floor(59.999999999)
outputting 59
But don't know why python is treating 0.2
as 0.2000000001
in the floor division
case but not in the division
case?
The reason why 12 / 0.2
results in 60.0, is not because 0.2 is treated differently, but because the error in the floating point division cancels the error in the representation of 0.2. The float always has the same value (greater than decimal 0.2), but depending on the operations those errors will either accumulate or be cancelled.
In other cases the error is not completely cancelled and shows up in the result:
>>> (12 / (0.2 * 0.2)) * 0.2
59.99999999999999
In CPython integer division for these specific types (float // float after the first param is automatically converted) and relative magnitudes is performed as follows (see Python's source code for the full method):
mod = a % b
result = (a - mod) / b
If b was actually 0.2, then mod
would be 0, but in floating point it is slightly larger, so mod
is just under 0.2.
If you do this manually you can see how we end up with 59.0:
>>> a = 12.0
>>> b = 0.2
>>> mod = a % b
>>> mod
0.19999999999999934
>>> (a - mod) / b
59.0
The OP is also asking about the error in the floating point division, here's that as well:
The values (mantissa * base^exponent):
12: 1.1000000000000000000000000000000000000000000000000000 * 2^3
0.2: 1.1001100110011001100110011001100110011001100110011010 * 2^(-3)
Remember 0.2 is not really 0.2, it's 0.200000000000000011102230246251565404236316680908203125. The result of dividing 12 by a value that is > 0.2 should be < 60.
To divide the values, we divide the mantissa and subtract the exponent, so we get:
12 / 0.2: 0.1110111111111111111111111111111111111111111111111111111 * 2^6
But the last 3 bits don't fit into a double, which only has 53 bits for the mantissa (including the sign) and we're currently using 56.
Since the result starts with 0, we first normalise, multiplying the mantissa by 2 and subtracting one from the exponent. And then we have to round to the nearest 53 bit mantissa:
normalised: 1.110111111111111111111111111111111111111111111111111111 * 2^5
rounded: 1.1110000000000000000000000000000000000000000000000000 * 2^5
1.1110000000000000000000000000000000000000000000000000 * 2^5 is equal to 60.
The difference between the correct result (1.110111111111111111111111111111111111111111111111111111 * 2^5) and the closest value we can represent as a 64 bit double (1.1110000000000000000000000000000000000000000000000000 * 2^5) is the error in the floating point division.