How safe is a set of floats?

Arnaud Delobelle arnodel at googlemail.com
Fri May 4 12:17:32 EDT 2007


On May 4, 3:21 pm, Thomas Nelson <t... at mail.utexas.edu> wrote:
> I want to generate all the fractions between 1 and limit (with
> limit>1) in an orderly fashion, without duplicates.
>
> def all_ratios(limit):
>     s = set()
>     hi = 1.0
>     lo = 1.0
>     while True:
>         if hi/lo not in s:
>             s.add(hi/lo)
>             yield (hi,lo)
>         hi += 1
>         if hi/lo > limit:
>             lo += 1
>             hi = lo
>
> I use a set to keep from giving duplicates; but is this safe?  In C
> they always tell you not to trust floating point equality comparisons,
> since they may not work as you expect.  My code seems fine for the
> limited amount I've tested, but I'm curious: is there a gaurantee
> about sets of floats?  Or a warning?

There won't be either, but you actually don't need to store the
previous fractions.  All you need to verify is that the denominator
and numerator are relatively prime (i.e. their gcd is 1).  That could
be implemented as:

------------------------------------
from itertools import count

def gcd(x, y):
    while x:
        x, y = y % x, x
    return y

def all_ratios(limit):
    for d in count(1):
        for n in xrange(d, int(limit*d) + 1):
            if gcd(d, n) == 1:
                yield n, d
------------------------------------

HTH

--
Arnaud




More information about the Python-list mailing list