[Python-Dev] math.hypot, complex.__abs__, and documentation

Mark Dickinson dickinsm at gmail.com
Wed Feb 17 14:05:46 CET 2010


[With apologies for Steven for the duplicate email.]

On Wed, Feb 17, 2010 at 12:22 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> Well, who am I to question Kahan?

Yes, there I go with the argument from authority.  But while we
shouldn't instantly accept Kahan's arguments just because he's Kahan,
it would be equally foolish for us mere mortals to ignore words from
one of the prime movers of the IEEE 754 standard. :-)

> I guess if you interpret nan as "indeterminate", than hypot(inf, nan)
> should be inf; but if you interpret it as "not a number", then it
> should be nan. Since NANs can be both, I guess we're stuck with one or
> the other.

Apart from the 'should be's, I think there's also a practical aspect
to consider:  I'm guessing that part of the reason for this sort of
behaviour is that it make it more likely for numerical code to 'do the
right thing' without extra special-case handling, in much the same way
that infinities can appear and disappear during a numerical
calculation, leaving a valid finite result, without the user having
had to worry about inserting special cases to handle those infinities.
 As an example of the latter behaviour, consider evaluating the
function f(x) = 1/(1+1/x) naively at x = 0;  if this formula appears
in any real-world circumstances, the chances are that you want a
result of 0, and IEEE 754's non-stop mode gives it to you.  (This
doesn't work in Python, of course, because it doesn't really have a
non-stop mode;  more on this below.)  Unfortunately, to back this
argument up properly I'd need lots of real-world examples, which I
don't have.  :(

> So I'm satisfied that there's a good reason for the
> behaviour, even if I'm not 100% convinced it's the best reason.

>From Python's point of view, the real reason for implementing it this
way is that it follows current standards (C99 and IEEE 754;  probably
also the Fortran standards too, but I haven't checked), so this
special case behaviour (a) likely matches expectations for numerical
users, and (b) has been thought about carefully by at least some
experts.

> On a related note, why the distinction here?
>
>>>> inf*inf
> inf
>>>> inf**2
> Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
> OverflowError: (34, 'Numerical result out of range')

For that particular example, it's because you haven't upgraded to
Python 2.7 yet.  :)

Python 2.7a3+ (trunk:78206M, Feb 17 2010, 10:19:00)
[GCC 4.2.1 (Apple Inc. build 5646) (dot 1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> float('inf') ** 2
inf

See http://bugs.python.org/issue7534.  But there are similar problems
that aren't fixed, and can't reasonably be fixed without causing
upset:

>>> 1e300 ** 2
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
OverflowError: (34, 'Result too large')
>>> 1e300 * 1e300
inf

Here I'd argue that the ideal Python behaviour would be to produce an
OverflowError in both cases;  more generally, arithmetic with finite
numbers would never produce infinities or nans, but always raise
Python exceptions instead.  But some users need or expect some kind of
'non-stop mode' for arithmetic, so changing this probably wouldn't go
down well.

Mark


More information about the Python-Dev mailing list