2

I'm using Python3 and getting different results when using // versus math.floor (other than return types).

My problem:

print('Using //: ', 1.0 // 0.2)
print('Using math.floor: ', math.floor(1.0 / 0.2))

Output:

Using //:  4.0
Using math.floor:  5

To me these should return the same results. PEP 238 says the following:

Floor division will be implemented in all the Python numeric types, and will have the semantics of: a // b == floor(a/b) except that the result type will be the common type into which a and b are coerced before the operation.

To me, this says that floor(a/b), when both a and b are floats, should return the same result. (Assuming that math.floor does floor division the same way as discussed in PEP 238). What major aspect of // am I missing that causes these results?

For system notes, I'm running Python 3.8.5 on MacOS within a virtual environment.

Edit

A rounding error might be the culprit, as 1.0 // 0.19 does return 5.0. However, why is the same error not apparent using math.floor?

John_335
  • 21
  • 5
  • 1
    `//` is more exact here, since 0.2 is actually represented by the computer with a number very slightly larger than 0.2. The closest floating-point value to the real quotient, though, is exactly 5.0 – so the information that it’s less than 5.0 is lost before `math.floor` sees it. – Ry- Apr 29 '22 at 02:55
  • 1
    You can see the exact values and exact result by going through `fractions.Fraction`: `Fraction(1.0) / Fraction(0.2)` is `18014398509481984 / 3602879701896397`, or about 4.999999999999999722444243844. `4.999999999999999722444243844 == 5.0`, so `math.floor(4.999999999999999722444243844) == 5.0`. – Ry- Apr 29 '22 at 02:58

0 Answers0