float("nan") in set or as key

S

Steven D'Aprano

If you're "fluent" in IEEE-754, then you won't find its behaviour
unexpected. OTOH, if you are approach the issue without preconceptions,
you're likely to notice that you effectively have one exception
mechanism for floating-point and another for everything else.

Returning a sentinel meaning "an exceptional event occurred" is hardly
unusual, even in Python. str.find() does is, as does re.search() and
re.match().

In any case, nobody says that NANs should replace exceptions for floats,
least of all the standard.


[...]
As for IEEE-754 saying that it's [NAN == NAN] True: they only really
had two choices: either it's True or it's False.

Incorrect. They could have specified that it was an error, like dividing
by zero, but they didn't. Instead, the standard specifies that there are
four mutually exclusive relationships possible:

greater than
less than
equal
unordered

and that comparisons should either return a code identifying the
relationship, or a True/False value. The standard allows for order
comparisons less_than(x, y) etc. in both signalling and quiet forms.

See section 7.11 of
http://www.validlab.com/754R/drafts/archive/2006-10-04.pdf

(the most recent draft of the 2008 standard I can find without paying for
the official standard).

NaNs provide "exceptions" even if the
hardware or the language lacks them, but that falls down once you leave
the scope of floating-point. It wouldn't have been within IEEE-754's
ambit to declare that comparing NaNs should return NaB (Not A Boolean).

Of course it would have been. That's effectively what the standard
actually does. Not "Not A Bool" per se, but comparisons can return
"Unordered", or they can signal.
 
N

Nobody

Returning a sentinel meaning "an exceptional event occurred" is hardly
unusual, even in Python. str.find() does is, as does re.search() and
re.match().

These are not "exceptional" conditions; if they were, an exception would
be used.

E.g. dict supports both d.get(key) and d[key] for lookups. The former
returns a sentinel, the latter raises an exception. The latter makes sense
if you "expect" the key to be present, the former if you don't.
As for IEEE-754 saying that it's [NAN == NAN] True: they only really
had two choices: either it's True or it's False.

Incorrect. They could have specified that it was an error, like dividing
by zero, but they didn't.

Specifying an error doesn't remove the requirement to also specify a
result. E.g. dividing a finite value by zero produces a result of
infinity. In languages which lack exceptions, errors only matter if the
code bothers to check for them (if such checks are even possible; C89
lacks <fenv.h>).
 
S

Steven D'Aprano

These are not "exceptional" conditions; if they were, an exception would
be used.


Exceptional does not mean rare or unexpected. Searching for a substring
returns the offset of that substring. If it is not found, that's the
exceptional case.

str.index raises an exception, and str.find returns a sentinel:
Traceback (most recent call last):
File said:
-1


As for IEEE-754 saying that it's [NAN == NAN] True: they only really
had two choices: either it's True or it's False.

Incorrect. They could have specified that it was an error, like
dividing by zero, but they didn't.

Specifying an error doesn't remove the requirement to also specify a
result.

Untrue, but irrelevant. (Standards often allow implementation-dependent
behaviour.) The standard *could* have said that NAN == NAN be an error,
but *didn't*, so what it should or shouldn't have done if it were an
error is irrelevant, because it's not an error.

And thus we come back full circle. Hundreds of words, and I'm still no
closer to understanding why you think that "NAN == NAN" should be an
error.
 
G

Grant Edwards

This analogy perhaps works better than expected. Whenever I swap
between Oz or NZ and the US-of-A, I have a brief mental clash that,
if I am not careful, could result in various bad things. :)

I find that I do mostly OK driving "on the wrong side of the road"
[except for the constant windshield/turn-signal mixups], but I have a
horrible time as a pedestrian.
 
G

Grant Edwards

I think that you misunderstood. What I was saying here was that, if you
wanted exception-on-NaN behaviour from Python, the interpreter wouldn't
need to call isnan() on every value received from the FPU, but rely upon
NaN-propagation and only call it at places where a NaN might disappear
(e.g. comparisons).

Ideed, I did misunderstand. I thought you were talking about a
the value of reducing the number of isnan() tests in user application
code.
Mathematically, it's undefined.

True, but we must be careful not to confuse math and scientific
calculation using fixed-length binary floting point.
But then IEEE-754 considers integers and floats to be completely
different beasts, while Python makes some effort to maintain a
unified "numeric" interface. If you really want IEEE-754
to-the-letter, that's undesirable, although I'd question the choice
of Python in such situations.

Python's minor issues with IEEE-754 are far outweighed by advantages
in other areas. :)
That's what exceptions are for. NaNs probably save a huge amount of
effort in languages which lack exceptions, but that isn't applicable
to Python.

How do you obtain using exceptions a behavior that's the same as with
quiet NaNs?

It was an attempt to illustate the overstatement to which it was a
reply.
 
N

Nobody

And thus we come back full circle. Hundreds of words, and I'm still no
closer to understanding why you think that "NAN == NAN" should be an
error.

Well, you could try improving your reading comprehension. Counselling
might help.

AFAICT, your main problem is that you can't distinguish between not
agreeing with a particular argument and being unable to even recognise
the existence of the argument.

A really big clue is here:
why you think that "NAN == NAN" should be an error

Given that my very first comment in the thread was:
That's overstating it. There's a good argument to be made for ...

I never said that it /should/ be an error, and later explicitly stated
that I wasn't arguing for it but pointing out that it's /arguable/.

But you appear unable to comprehend such distinctions. Don't agree with
the argument, don't accept the argument, don't recognise that there is an
argument; these all appear to be the same thing.
 
C

Chris Angelico

Thank you for your concern about my mental health.

Mental health? You're a programmer. It's far too late to worry about that.

My name is Chris, and I'm a programmer. It started when I was just a
child - my parents thought it would be alright for me to get into
these sorts of things. Kept me busy when they wanted to work. But it
grew from there. I was programming after school; I was programming
instead of going to bed. My social life deteriorated until I found I
was more interested in programming than in going to parties. When I
found myself writing programs during dinner, I knew I was an addict.
So I came to Prog-Anon, with their 12-step ...... ARGH! I can't
escape!!

Chris Angelico
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,802
Messages
2,569,663
Members
45,433
Latest member
andrewartemow

Latest Threads

Top