classification
Title: inf == inf (wrong IEEE 754 behaviour)
Type: behavior Stage:
Components: None Versions: Python 3.0, Python 2.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Cyborg16, mark.dickinson, tim.peters
Priority: normal Keywords:

Created on 2009-08-10 13:44 by Cyborg16, last changed 2009-08-10 16:29 by mark.dickinson. This issue is now closed.

Messages (5)
msg91443 - (view) Author: D Hardy (Cyborg16) Date: 2009-08-10 13:44
Currently python evaluates infinity as equal to itself in my tests (2.6.2 and 3.0.1+
from ubuntu). I'm not entirely sure whether the behaviour of 'inf == inf' is specified
by IEEE 754, but it leads to results like:

>>> 1e400
inf
>>> 1e400 == 1e500
True

And hence unittests which use tests like

if not (math.fabs(value1 - value2) <= 0.00000001 *
max(math.fabs(value1),math.fabs(value2))):
    fail

don't always fail when they should (when a value is inf).

This is a specific example (and probably not the recommended way of testing
values in any case), but I think "inf != inf" is generally considered the correct
behaviour. (Although maybe this is left over from the PEP 42 / PEP 754 mess; I
wasn't able to find the current status of implementing IEEE 754 behaviour in
python.)
msg91445 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2009-08-10 14:06
+inf == +inf, and -inf == -inf, are required by the 754 standard. 
However, +inf - +inf, and -inf - -inf, are required (by the same
standard) to signal invalid operation and, if that signal is masked (as
it is in Python), to return a NaN.  Then NaN == x is false for any value
of x (including a NaN).

OTOH, +inf != -inf, +inf - -inf == +inf, and -inf - +inf == -inf.

Current versions of Python implement all of that.
msg91446 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-08-10 14:16
Section 5.11 of IEEE 754-2008, paragraph 2, says:

"""Infinite operands of the same sign shall compare equal."""

So Python's behaviour follows the standard here.

Producing 'is close to' tests is always tricky if you want to be able to
deal with IEEE special values (subnormals, negative zero, infinities, 
NaNs).  You could always write your unittest as:

if not (value1 == value2 or <relative_error_test>).

but this still doesn't consider NaNs, and probably doesn't do what you 
want for subnormals either.

Closing as invalid.
msg91451 - (view) Author: D Hardy (Cyborg16) Date: 2009-08-10 16:03
Oh; OK, thanks for the response.

Sorry, I've used +/- inf and NaN values in other languages and was under the
impression inf != inf under IEEE 754. I think this requires explicitly testing for
infinity then.

For anyone interested, I've written a test which seems to work well. Sub-normals I
don't think are an issue since it doesn't deal with the binary representation (it was
never intended to be computationally efficient). It's at:
http://code.google.com/p/openmalaria/source/browse/trunk/test/compareOutputsFl
msg91453 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-08-10 16:29
The only issue with subnormals is that a simple relative error test is 
usually inappropriate.  For example, on an IEEE 754 machine 2**-1073 
should almost always be considered a good approximation to 2**-1074, since 
the two floats are adjacent; but the relative error here is 100%!  But I 
see that in the code you linked you have a combination of a relative error 
and absolute error tests, so this isn't a problem.

There's something similar to your code in the Python tests:  see function 
'almostEqualF' in Lib/test/test_cmath.py.
History
Date User Action Args
2009-08-10 16:29:27mark.dickinsonsetmessages: + msg91453
2009-08-10 16:03:23Cyborg16setmessages: + msg91451
2009-08-10 14:16:18mark.dickinsonsetstatus: open -> closed

nosy: + mark.dickinson
messages: + msg91446

resolution: not a bug
2009-08-10 14:06:04tim.peterssetnosy: + tim.peters
messages: + msg91445
2009-08-10 13:44:24Cyborg16create