0

First of all, sorry if this has been already answered, I have been searching for a while and did not find anything.

In short, I'm trying to create a programe to automate some tasks I have. In one, I have a loop on days, between a start date and an end date. For each iteration, I'm trying to get the lag in months between the current date and the start date. So I tried to use the euclidean division, which seemed appropriate. Bottom line is, it works for almost all dates except a few, for instance:

import datetime as dt
start=dt.date(2022, 7, 1)
end=dt.date(2023, 7, 1)
average_days=365/12

lag1=(end-start).days/average_days
lag2=(end-start).days//average_days

For these dates in particular, lag1 gives me 12 while lag2 gives me 11. Where does this difference come from exactly, and how can I work around this issue to continue using the euclidean division ?

Thank you

MFA
  • 23
  • 4
  • 3
    What do you mean by "euclidean division"? – Scott Hunter Mar 02 '22 at 15:49
  • I mean getting the quotient of the division, which is what I do in the definition of lag2 – MFA Mar 02 '22 at 15:54
  • It's a bit weird, but I think the problem comes from float precision. If you look at the rest `365%average_days` it gives `30.416666666666654`, which is slightly lower than `average_days` at `30.416666666666668` – VicN Mar 02 '22 at 15:58
  • For reference, Python refers to this operation as ["floor division"](https://docs.python.org/3/glossary.html#term-floor-division). – 0x5453 Mar 02 '22 at 15:58

1 Answers1

5

This is answered here:

Dividing a Number by a Decimal Using the Integer Division Operator

In short, 365/12 is a float and is not exact after a certain number of digits. And could be a tiny bit larger than what you would expect. So when you divide 365 by this number it will be 11.99999... And // is floor division which truncates the decimals, resulting in 11.

Tim
  • 3,178
  • 1
  • 13
  • 26
  • 1
    To correct this problem, I have a solution but it's a bit hacky (and there might be better ways): test if `np.isclose(365%average_days, average_days)`, and when it is, add 1 to lag2 – VicN Mar 02 '22 at 16:04
  • 1
    Best practice in general would be to flag/vote to close a question as a duplicate. – General Grievance Mar 05 '22 at 15:20