[Python-Dev] Not-a-Number

Robert Kern robert.kern at gmail.com
Fri Apr 29 22:54:52 CEST 2011


On Fri, Apr 29, 2011 at 11:35, Alexander Belopolsky
<alexander.belopolsky at gmail.com> wrote:
> On Fri, Apr 29, 2011 at 11:31 AM, Robert Kern <robert.kern at gmail.com> wrote:
> ..
>> And in fact, 0.0/0.0 is covered by the more general rule that x/0.0 raises
>> ZeroDivisionError, not a rule that converts IEEE-754 INVALID exceptions into
>> Python exceptions.
>
> It is unfortunate that official text of IEEE-754 is not freely
> available and as a result a lot of discussion in this thread is based
> on imperfect information.
>
> I find Kahan's "Lecture Notes on the Status of IEEE Standard 754 for
> Binary Floating-Point Arithmetic" [1] a reasonable reference in the
> absence of the official text.   According to Kahan's notes, INVALID
> operation is defined as follows:
>
> """
> Exception: INVALID operation.
>
> Signaled by the raising of the INVALID flag whenever an operation's
> operands lie outside its domain, this exception's default, delivered
> only because any other real or infinite value would most likely cause
> worse confusion, is NaN , which means “ Not a Number.” IEEE 754
> specifies that seven invalid arithmetic operations shall deliver a NaN
> unless they are trapped:
>
>    real √(Negative) , 0*∞ , 0.0/0.0 , ∞/∞,
>    REMAINDER(Anything, 0.0) , REMAINDER( ∞, Anything) ,
>    ∞ - ∞ when signs agree (but ∞ + ∞ = ∞ when signs agree).
>
> Conversion from floating-point to other formats can be INVALID too, if
> their limits are violated, even if no NaN can be delivered.
> """
>
> In contrast, Kahan describes DIVIDE by ZERO exception as "a misnomer
> perpetrated for historical reasons. A better name for this exception
> is 'Infinite result computed Exactly from Finite operands.'"

Nonetheless, the reason that *Python* raises a ZeroDivisionError is
because it checks that the divisor is 0.0, not because 0.0/0.0 would
issue an INVALID signal. I didn't mean that 0.0/0.0 is a "Division by
Zero" error as defined in IEEE-754. This is another area where Python
ignores the INVALID signal and does its own thing.

>> Other operations that produce a NaN and issue an IEEE-754
>> INVALID signal do not raise a Python exception.
>
> Some do:
>
>>>> math.sqrt(-1)
> Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
> ValueError: math domain error

Right. Elsewhere I gave a more exhaustive list including this one. The
other is int(nan), though that becomes a Python exception for a more
fundamental reason (there is no integer value that can represent it)
than that the IEEE-754 standard specifies that the operation should
signal INVALID. Arithmetic operations on signalling NaNs don't raise
an exception either.

These are the minority *exceptions* to the majority of cases where
operations on Python floats that would issue an INVALID signal do not
raise Python exceptions. If you want to lump all of the inf-related
cases together, that's fine, but arithmetic operations on signalling
NaNs and comparisons with NaNs form two more groups of INVALID
operations that do not raise Python exceptions.

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco


More information about the Python-Dev mailing list