The CPython's implementation of floor division of a float number, as either a dividend or a divisor, lies in the float_floor_div
function, which calls the float_divmod
function (which implements the divmod
function) for the actual calculation, which, with the following lines of code:
mod = fmod(vx, wx);
div = (vx - mod) / wx;
...
floordiv = floor(div);
tells you that the way that floor division works for a float number is to first call the fmod
function to obtain the remainder of the division, subtract the remainder from the dividend vx
, and then divide it by the divisor wx
, before applying the floor
function on the resulting quotient div
.
And if you try performing the modulo operation of 4 % 0.4
, expecting it to be 0
because 4 / 0.4 should be mathematically 10:
>>> 4 % 0.4
0.3999999999999998
You'll see the classic floating error inherent from the way decimal numbers are approximated by the binary system. As a result 0.4 is actually stored as something slightly greater than 0.4, which you can verify by instantiating a high-precision Decimal
object with 0.4:
>>> from decimal import Decimal
>>> Decimal(0.4)
Decimal('0.40000000000000002220446049250313080847263336181640625')
which is why 4 % 0.4 has a remainder of 0.3999999999999998 instead of 0, and as a result, with the way float_divmod
calculated the quotient, by first subtracting the remainder from the dividend, you get:
>>> 4 - 4 % 0.4
3.6
so naturally,
>>> (4 - 4 % 0.4) / 0.4
9.0