math.nroot [was Re: A brief question.]

George Sakkis gsakkis at rutgers.edu
Mon Jul 4 07:36:34 EDT 2005


"Steven D'Aprano" <steve at REMOVEMEcyber.com.au> wrote:

> But it doesn't make sense to say that two flags are equal:
>
> keep_processing = True
> more_reading_needed = True
> while more_reading_needed and keep_processing:
>      get_more_records()
>      process_records()
> if not keep_processing:
>      print "User clicked Cancel"
>
> What does it mean to say that the flag done_processing
> is equal to the flag more_reading_needed? (That is not
> the same question as asking if the two flags have the
> same value.)

Huh ? Equality *is* the answer to whether two "things" (flags or
whatever) have the same value or not. What else could it be ? Certainly
not whether they are *the same*; you have the 'is' operator for
checking identity. In any case, "done_processing ==
more_reading_needed" is perfectly valid and most people would agree
that if the result is True, "done_processing" and "more_reading_needed"
are equal.

> It gets worse. Consider this example of "logic":
>
> x = log(-5)  # a NaN
> y = log(-2)  # the same NaN
> x == y  # you want this to be true for NaNs
>
> Then:
>
> # compare x and y directly
> log(-5) == log(-2)
> # if x == y then exp(x) == exp(y) for all x, y
> exp(log(-5)) == exp(log(-2))
> -5 == -2

Such paradox cases can be avoided if the only operations defined for
NaNs are equality/inequality; all others yield NaN too. That is,
exp(NaN) is NaN, as it is log(NaN), 3**NaN / 5i and so on. Think of NaN
as a black hole that absorbs and assimilates what falls into it, so
log(-5) and log(-2) are just NaN, they lose their "identity" as two
distinct things, "log(-5)" and "log(-2)".

> > Similarly, if z=0/0, z would also be invalid, but
> > different from x and y, since it is the result of a different invalid
> > operation. This brings us to the many-NaN situation.
>
> The problem is, the many NaNs in the IEEE standard (or
> at least Apple's implementation of it) refer to _kinds_
> of NaNs, not NaNs themselves.
>
> log(-2) is not the same "not a number" as log(-2.0001),
> or log(-2.3). They might be the same "kind" of failure,
> but that's it.

That's absolutely fine; as long as two "things" are invalid and they're
invalid for the same reason ("kind of failure"), they are equal to me.

> Having given reasons why it is utterly bogus to be
> comparing NaNs for equality, I will say this.
> Practicality beats purity. If you can demonstrate a
> good usage case for testing equality with NaNs, I will
> accept that it is a good thing to do.
>
> if x in (SOME_NAN, SOME_OTHER_NAN, ANOTHER_NAN, \
>      YET_ANOTHER_NAN, AND_ANOTHER_NAN, ..., \
>      # 240+ more NaNs listed
>      ALMOST_FINISHED_NOW, LAST_NAN):
>      print "Calculation failed!"
>
> is _not_ a good usage case, since it is best handled with:
>
> if isNan(x):  # handled by the floating point package
>      print "Calculation failed!"

Agreed on that, if all you need to know is if the outcome of an
expression is valid or not. But since a NaN can be thought of as "a
flag representing the fact that an error occurred", as you mentioned,
it makes sense in practice to ask whether two errors are of the same
kind, e.g. for handling them differently. If I understood correctly,
your objection is using the equality operator '==' with these semantics
for NaNs. I would say that it's a reasonable choice for "practicality
beats purity" reasons, if nothing else.

George




More information about the Python-list mailing list