George Sakkis wrote: > "Tom Anderson" <[EMAIL PROTECTED]> wrote: > > >>>But NaNs are _not_ things. >> >>I disagree. A NaN _is_ a thing; it's not a floating-point number, for >>sure, but it is a symbol which means "there is no answer", or "i don't >>know", and as such, it should follow the universal rules which apply to >>all things. > > > It seems that the standard semantics of NaN is closer to NULL values in > ANSI SQL, that is "unknown", "not available". In this sense, if you > have two 'things' you don't know, you can't say they are equal simply > because you don't know them !
It isn't that they are unknown. They don't exist, so you can't compare them! The bit-patterns that represent NaNs should not be thought of as "the answer to the calculation", but merely "a flag representing the fact that an error occurred". The nice thing is that the flag can propogate through your calculations, so you can defer testing for an error condition until the very end, but it is not a value. When you think of NaNs as flags, the question of equality doesn't apply. You can compare two flags bit by bit to see if they have the same bit pattern, and that's what the isNan() function is for: test if a float has a bit pattern that represents a NaN. 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.) >>>Since INF-INF doesn't have an answer, we can't do this: >>> >>>x = inf - inf >>>y = inf - inf >>> >>>and expect that x == y. >> >>I think we can. Both x and y have the same value, a value of >>indeterminacy. NaN is a rigidly defined value of doubt and uncertainty! > > > In this case, however, I would agree. x and y above are not assigned a > label of 'unknown'; they are derived from an operation among valid > *known* values, so NaN here means 'invalid' rather than 'unknown'.It > makes sense to have x==y, because x and y are the outcome of the *same* > invalid operation. This is incorrect. Mathematically, you CAN'T say: x = INF - INF y = INF - INF therefore x = y. This is just _wrong_. Mathematically, x and y don't exist, so they can't be equal since equality is only defined for things which exist. 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 > 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. You can't even say that log(-2) == log(-2), because equality is only defined for numbers, not "no such thing". 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!" -- Steven. -- http://mail.python.org/mailman/listinfo/python-list