
[With apologies for Steven for the duplicate email.] On Wed, Feb 17, 2010 at 12:22 PM, Steven D'Aprano <steve@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