float("nan") in set or as key

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sat Jun 4 22:03:03 EDT 2011


On Sat, 04 Jun 2011 16:49:40 -0500, Robert Kern wrote:

> Steven is being a little hyperbolic. Python does not fully conform to
> all of the details of the IEEE-754 specification, though it does conform
> to most of them. 

I'm not sure that "most" is correct, but that depends on how you count 
the details. Let's just say it has partial support and let's not attempt 
to quantify it.

(Which is a big step up from how things were even just a few years ago, 
when there wasn't even a consistent way to create special values like INF 
and NAN. Many thanks to those who did that work, whoever you are!)


> In particular, it raises an exception when you divide
> by 0.0 when the IEEE-754 specification states that you ought to issue
> the "divide by zero" or "invalid" signal depending on the numerator (and
> which may be trapped by the user, but not by default) and will return
> either an inf or a NaN value if not trapped. Thus, the canonical example
> of a NaN-returning operation in fully-conforming IEEE-754 arithmetic,
> 0.0/0.0, raises an exception in Python. You can generate a NaN by other
> means, namely dividing inf/inf.

But it's inconsistent and ad hoc. The guiding philosophy of Python 
floating point maths appears to be:

(1) Python will always generate an exception on any failed operation, and 
never a NAN or INF (I believe I've even seen Guido explicitly state this 
as a design principle);

(2) arithmetic expressions and maths functions will usually, but not 
always, honour NANs and INFs if you provide then as input.

I see this thread being driven by people who have failed to notice that 
(1) already applies, and so pure Python will never give them a NAN they 
didn't explicitly create themselves, but want to remove (2) as well.

Personally I think Python would be a better language if it *always* 
returned NANs and INFs for failed float operations, but I recognise that 
I'm in a minority and that many people will prefer exceptions. Even 
though I think Guido is wrong to believe that exceptions are more newbie 
friendly than NANs (my Hypercard experience tells me differently), I 
accept that opinions differ and I'm happy for exceptions to be the 
default behaviour.

But it makes me rather annoyed when people who know nothing about 
IEEE-754 special values, their uses and justification, come along and 
insist that the only right answer is to throw away what little support 
for them we have.


> One other deviation is the one which you were asking about. The standard
> does say that the "invalid" signal should be issued in most
> circumstances that generate a NaN and that the user should be able to
> trap that signal. Python explicitly disables that mechanism. It used to
> provide an optional module, fpectl, for providing a signal handler for
> those. However, creating a handler for such a low-level signal in a
> high-level language like Python is inherently unsafe, so it is not
> really supported any more.

More unsafe than ctypes?

In any case, I believe that in Python, catching an exception is more or 
less the moral equivalent to trapping a low-level signal.


> The decimal module mostly gets it right. It translates the signals into
> Python exceptions that can be disabled in a particular context.

All I want for Christmas is for floats to offer the same level of 
IEEE-754 support as decimal, only faster. And a pony.



-- 
Steven



More information about the Python-list mailing list