0

I'm not sure if this is a bug or if I'm just misunderstanding how integer division is supposed to work.

Consider the following code:

import math
a = 18000
b = 5500
c = (a-b)/9  # c = 1388.(8)

d = (a-b)/c
e = (a-b)//c
f = math.floor(d)
print(f"(a-b)/c={d}, (a-b)//c={e}, floor={f}")  # outputs (a-b)/c=9.0, (a-b)//c=8.0, floor=9

Why is e different from d? As far as I understand, num1//num2 should be equal to math.floor(num1/num2).

Using Python 3.8.10 32bit on Windows 10 Pro.

  • There's non-integer operations at work here. You have floating point numbers, like `c`. Check whether those are exact. – gspr Feb 16 '23 at 13:55

2 Answers2

2

The difference here is the use of intermediate calculations.

See this question for more details on floating point representation.

(a-b)/9 is not exactly representable in floating point. In python it is stored as 1388.888888888888914152630604803562164306640625

from decimal import Decimal
print(Decimal(c))  # 1388.888888888888914152630604803562164306640625

Observe that c is actually a little larger than the true value of (a-b)/9. Because of this, the true value of (a-b)/c is slightly less than 9. Floor-divide in python gives the floor of the true value of the division, therefore (a-b)//c correctly evaluates to 8.

On the other hand, (a-b)/c results in another floating point precision error. Though the true value is slightly less than 9, the closest value that can be represented is exactly 9. Applying the floor operation to exactly 9 results in 9, as expected.

jodag
  • 19,885
  • 5
  • 47
  • 66
0

Because c is a non-integer number of float type, the integer-division // can lead to unintuitive results. Best to only use // when dividing 2 integers with the purpose of creating an int as output type.

Thijs
  • 433
  • 8