The reason it’s failing is unfortunately because of how large your numbers are becoming. The reason it’s failing for your last few indices is because of how floating-point division is being handled in Python 2. Take note: this article was written with Python 3 in mind; however I was able to reproduce your results with Python 2.7
I opened up a Python 2 and set up everything like the code you provided. Since you wanted to find the entry at total — 1
, this is equivalent to running iterator.entryAt(150094635296999120)
. This is still in range and far below the size of sys.maxsize
. So, to test this out I’ll create a variable n
and assign it the value of total — 1
.
We can see in the algorithm for entryAt
that in the for
loop we are performing this calculation (I’ve modified it to Python 2 syntax since math behaves differently between 2 and 3):
combination.append(self.sets[i][long(math.floor(n / self.divs[i])) % self.mods[i]])
Since everything seems to go haywire when we get to the 34th position, let’s test what these values would be in the loop. Here are the respective values for self.divs[i]
and self.mods[i]
:
self.divs[34] = 3L
self.mods[34] = 3L
This is where the limitations of computing unfortunately come into play. If execute this command in a Python 2 shell, you’ll get this result:
>>> n
150094635296999120
>>> n / 3# Remember, this is 150094635296999120 / 3
50031545098999706
>>> 50031545098999706 * 3
150094635296999118 # This is not correct
>>> 50031545098999706 * 3 == n # Sanity-check
False
See the issue? Because of floating-point division and how Python rounds things, this isn’t giving us the correct value. Once numbers start getting high enough, Python (and most languages) begin to struggle to represent a number with enough floating-point accuracy. This is why we run into those issues and get incorrect indexes returned. What we SHOULD be getting is 2 when we perform this, however we’ll see that this simply isn’t the case, even if we cast everything to a float
:
>>> math.floor(float(n) / float(3)) % float(3) == 2
False
If you take a look here in the docs https://docs.python.org/2/tutorial/floatingpoint.html#representation-error they discuss this in full.
I realize this doesn’t solve the issue, but I hope this at least helps explain why this fails when it reaches numbers that large.