2025-07-24 –, Main Room 1 (Main stage)
When you write a float range like 0.1:0.2:0.7 it seems obvious that you want the elements to be 1/10, 3/10, 5/10, 7/10. But the floating-point numbers 0.1, 0.2 and 0.7 are not exactly 1/10, 2/10 and 7/10—they are approximations of the form m/2^p. Guessing what any given float range was intended to mean turns out to be shockingly hard. Julia currently uses a heuristic that mostly works but still has some rather unfortunate failures. This talk explores how to solve this problem once and for all.
In the float range 0.1:0.2:0.7, how does one guess that 0.1 was actually intended to be 1/10? Julia currently computes the simplest fraction for each float and then checks if the resulting interpretation is valid—i.e. does the step divide the width exactly? If that doesn’t work, it gives up, which can lead to rather bad behavior, including ranges that are too short and interior points that are wrong. There are cases where a simple interpretation of a range exists, but rationalizing the float values independently doesn’t find it—the start, step and stop need to considered together in order to find the "right" interpretation. This problem is unexpectedly hard to solve in a principled and general way.
This talk first defines what it means for a triple of rationals to be a valid interpretation of a floating-point range. We then consider how to pick a single interpretation among the infinite possibilities as the best one. This problem is partly definitional and partly algorithmic: we want a definition that makes sense and produces intuitive results, but we also need it to be efficiently computable—every time we construct a float range object. The mathematics required to find an optimal interpretation of a range turn out to be unexpectedly deep, touching on integer linear programming, numerical semigroup theory, and the Stern-Brocot tree of fractions.
Julia co-creator and JuliaHub co-founder.