float("nan") in set or as key
Nobody
nobody at nowhere.com
Wed Jun 1 16:41:06 EDT 2011
On Sun, 29 May 2011 23:31:19 +0000, Steven D'Aprano wrote:
>> That's overstating it. There's a good argument to be made for raising an
>> exception.
>
> If so, I've never heard it, and I cannot imagine what such a good
> argument would be. Please give it.
Exceptions allow you to write more natural code by ignoring the awkward
cases. E.g. writing "x * y + z" rather than first determining whether
"x * y" is even defined then using a conditional.
>> Bear in mind that an exception is not necessarily an error,
>> just an "exceptional" condition.
>
> True, but what's your point? Testing two floats for equality is not an
> exceptional condition.
NaN itself is an exceptional condition which arises when a result is
undefined or not representable. When an operation normally returns a
number but a specific case cannot do so, it returns not-a-number.
The usual semantics for NaNs are practically identical to those for
exceptions. If any intermediate result in a floating-point expression is
NaN, the overall result is NaN. Similarly, if any intermediate calculation
throws an exception, the calculation as a whole throws an exception.
If x is NaN, then "x + y" is NaN, "x * y" is NaN, pretty much anything
involving x is NaN. By this reasoning both "x == y" and "x != y" should
also be NaN. But only the floating-point types have a NaN value, while
bool doesn't. However, all types have exceptions.
>>> The correct answer to "nan == nan" is False, they are not equal.
>>
>> There is no correct answer to "nan == nan".
>
> Why on earth not?
Why should there be a correct answer? What does NaN actually mean?
Apart from anything else, defining "NaN == NaN" as False means that
"x == x" is False if x is NaN, which violates one of the fundamental
axioms of an equivalence relation (and, in every other regard, "==" is
normally intended to be an equivalence relation).
The creation of NaN was a pragmatic decision on how to handle exceptional
conditions in hardware. It is not holy writ, and there's no fundamental
reason why a high-level language should export the hardware's behaviour
verbatim.
>> Arguably, "nan != nan" should also be false,
>> but that would violate the invariant "(x != y) == !(x == y)".
>
> I cannot imagine what that argument would be. Please explain.
A result of NaN means that the result of the calculation is undefined, so
the value is "unknown". If x is unknown and y is unknown, then whether x
is equal to y is itself unknown, and whether x differs from y is also
unknown.
More information about the Python-list
mailing list