You can get much farther by storing a fraction. Still, a midpoint is not the most effective point to chose. One solution I&#x27;ve explored is in the form of fractions generated by the Stern-Brocot tree. The continued fraction representation is easy to work with and can easily be turned into other representations.<p>With that, you could pick ideal points between bounds very cheaply:<p><pre><code>  (1&#x2F;4, 1&#x2F;2) → 1&#x2F;3
  (4&#x2F;3, 5&#x2F;2) → 2&#x2F;1
  (5&#x2F;4, 7&#x2F;5) → 4&#x2F;3
</code></pre>
In languages with large integers, it&#x27;s quite easy to store two numbers. In a language like JavaScript, 53 bits of the mantissa in a double floating point number give 70+ moves [1] before you&#x27;d have to worry about losing precision, and if that were a deal breaker, a continued fraction is very cheap to store instead.<p>If people are interested, I&#x27;d be happy to share some implementations I&#x27;ve got in a number of languages including Erlang and JavaScript (I&#x27;m rewriting these from a prior version I did which used a slightly less optimal path representation).<p>[1] These are worst case. Most interactions could survive 1000+ resorts in practice. I&#x27;ve yet to see any of the components outgrow the 53bit mantissa of a double in JavaScript. The worse case grows with the Fibonacci sequence which is easy to see once you learn more about the Stern-Brocot tree structure. Even when they do grow large though, it&#x27;s easy to switch to the continued fraction representation which solves this problem.<p>EDIT: Here is a short list of indices from a production database where it&#x27;s easy to see why fractions are far superior to floating point indices: <a href="https:&#x2F;&#x2F;gist.github.com&#x2F;strmpnk&#x2F;d4afe4bb5bb69b46631b" rel="nofollow">https:&#x2F;&#x2F;gist.github.com&#x2F;strmpnk&#x2F;d4afe4bb5bb69b46631b</a>