[Python-ideas] [Python-Dev] The Case Against Floating Point ==
Imri Goldberg
lorgandon at gmail.com
Thu Mar 13 16:09:43 CET 2008
As per Aahz's suggestion, I'm moving this discussion here, from Python-Dev.
(Thanks Aahz!)
Mark Dickinson wrote:
> On Thu, Mar 13, 2008 at 4:20 AM, Imri Goldberg <lorgandon at gmail.com
> <mailto:lorgandon at gmail.com>> wrote:
>
> My suggestion is to do either of the following:
> 1. Change floating point == to behave like a valid floating point
> comparison. That means using precision and some error measure.
> 2. Change floating point == to raise an exception, with an error
> string
> suggesting using precision comparison, or the decimal module.
>
>
> I don't much like either of these; I think option 1 would cause
> a lot of confusion and difficulty---it changes a conceptually
> simple operation into something more complicated.
>
> As for option 2., I'd agree that there are situations where having
> a warning (not an exception) for floating-point equality (and
> inequality) tests might be helpful; but that warning should be
> off by default, or at least easily turned off.
As I said earlier, I'd like static checkers (like Python-Lint) to catch
this sort of cases, whatever the decision may be.
>
> Some Fortran compilers have such a (compile-time) warning,
> I believe. But Fortran's users are much more likely to be
> writing the sort of code that cares about this.
>
>
> Since this change is not backwards compatible, I suggest it be added
> only to Python 3.
>
>
> It's already too late for Python 3.0.
Still, I believe it is worth discussing.
>
>
> 3. Programmers will still need the regular ==:
> Maybe, and even then, only for very rare cases. For these, a special
> function\method might be used, which could be named floating_exact_eq.
>
>
> I disagree with the 'very rare' here. I've seen, and written, code like:
>
> if a == 0.0:
> # deal with exceptional case
> else:
> b = c/a
> ...
>
> or similarly, a test (a==b) before doing a division by a-b. That
> one's kind of dodgy, by the way: a != b doesn't always guarantee
> that a-b is nonzero, though you're okay if you're on an IEEE 754
> platform and a and b are both finite numbers.
While checking against a==0.0 (and other similar conditions) before
dividing will indeed protect from outright division by zero, it will
enlarge any error you will have in the computation. I guess it would be
better to do the same check for 'a is small' for appropriate values of
'small'.
>
> Or what if you wanted to generate random numbers in the open interval
> (0.0, 1.0). random.random gives you numbers in [0.0, 1.0), so a
> careful programmer might well write:
>
> while True:
> x = random.random()
> if x != 0.0:
> break
>
> (A less fussy programmer might just say that the chance
> of getting 0.0 is about 1 in 2**53, so it's never going to happen...)
>
> Other thoughts:
>
> - what should x == x do?
If suggestion no. 1 is accepted, always return True. If no. 2 is
accepted, raise an exception.
Checking x==x is as meaningful as checking x==y.
> - what should
>
> 1.0 in set([0.0, 1.0, 2.0])
>
> and
>
> 3.0 in set([0.0, 1.0, 2.0])
>
> do?
>
Actually, one of the reasons I thought about this subject in the first
place, was dict lookup for floating point numbers. It seems to me that
it's something you just shouldn't do.
As for your examples, I believe these two should both raise an
exception. This is even worse than normal comparison - here you are
checking against the hash of a floating point number. So if you do that
in the current implementation, there's a good chance you'll get
unexpected results. If you do that given the implementation of
suggestion 1, you'll have a hard time make set work.
> Mark
Cheers,
Imri.
-------------------------
Imri Goldberg
www.algorithm.co.il/blogs
www.imri.co.il
-------------------------
Insert Signature Here
-------------------------
More information about the Python-ideas
mailing list