How to test if one float is an integer multiple of another?

The moment you represent your numbers in floating point, it’s already too late. The number 1/10 cannot be represented in binary floating point with any finite precision for the same reason that 1/3 cannot be represented in any finite precision decimal value (they’re both just infinitely repeating fractions in their respective bases).

You can use Rational numbers, which will give you the exact right answer.

But if you’re somehow stuck with floating-point inputs, then you’re going to have to make up your own tolerances. For example, you could check something like:

julia> check(a, b) = isapprox(round(b / a) * a, b)
check (generic function with 1 method)

julia> check(0.1, 0.2)
true

julia> check(0.1, 0.25)
false

julia> check(0.1, 0.3)
true

Of course, this has edge cases too:

julia> check(0.1, 0.0)  # should be true, and is
true

julia> check(0.1, 1e-16)  # what should this be? Not obvious...
false

julia> check(0.1 + 1e-16, 0.2)   # seems like this should match the one above...
true

What is preventing you from taking exact rational inputs if you actually want exact numerical results here?

7 Likes