Tyler Burdsall
2 min readNov 11, 2018

--

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.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Tyler Burdsall
Tyler Burdsall

Written by Tyler Burdsall

A software developer in Portland with too many opinions

Responses (1)

Write a response