[ python-Bugs-899109 ] 1==float('nan')

SourceForge.net noreply at sourceforge.net
Thu Feb 19 14:01:16 EST 2004


Bugs item #899109, was opened at 2004-02-17 21:47
Message generated for change (Comment added) made by mwh
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=899109&group_id=5470

Category: Python Interpreter Core
Group: Python 2.3
Status: Open
Resolution: None
Priority: 5
Submitted By: Arman Bostani (arman0)
Assigned to: Nobody/Anonymous (nobody)
Summary: 1==float('nan')

Initial Comment:
In python 2.3.1 on Linux/x86, X==float('nan') evaluates
to True given any number value for X.  I admit to not
knowing much about IEEE arithmetic.  But, is this Kosher?

-arman
 

----------------------------------------------------------------------

>Comment By: Michael Hudson (mwh)
Date: 2004-02-19 19:01

Message:
Logged In: YES 
user_id=6656

Consider the attached.  It implements rich comparisons for
floats, which makes the behaviour on linux at least very
much less silly.  All tests except for the
considered-hopeless-on-this box audio tests and the new
test_tcl pass.  Even test_bsddb passed! Twice!  (I'm not
sure I can claim credit for this :-)

----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2004-02-19 17:34

Message:
Logged In: YES 
user_id=31435

Sorry, the patch can't work:  C89 says nothing about what 
happens when NaNs are compared, and it's in fact not the 
case across platforms that "x != x" returns 1 when x is a NaN.

The most important counter-example for Python is that the 
following prints

1.#INF
-1.#IND
1

under MSVC 6.

#include <stdio.h>

void main()
{
    double x = 1e300 * 1e300;
    printf("%g\n", x);
    x -= x;
    printf("%g\n", x);
    printf("%d\n", x == x);
}


----------------------------------------------------------------------

Comment By: Paul Eggert (eggert)
Date: 2004-02-19 06:39

Message:
Logged In: YES 
user_id=17848

There's an easy fix.  Python has long mishandled IEEE
special values
(see bugs 445484 and 737648, and see PEP 42 "Non-accidental
IEEE-754
support" as well as PEP 754), and solving the problem in
general will
be some work.  However, solving the NaN-comparison problem
is easy:
simply sort NaNs consistently before all numbers.  This is
the same
algorithm that GNU "sort -g" has used for quite some time.

===================================================================
RCS file: Include/pyport.h,v
retrieving revision 2.3.3.0
diff -pu -r2.3.3.0 Include/pyport.h
--- Include/pyport.h	2003/09/30 14:56:50	2.3.3.0
+++ Include/pyport.h	2004/02/19 06:06:10
@@ -221,6 +221,13 @@ extern "C" {
 #define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE)
 #endif
 
+/* Py_IS_NAN(X)
+ * Return 1 if float or double arg is not a number (NaN),
else 0.
+ * Caution:
+ *    X is evaluated more than once.
+ */
+#define Py_IS_NAN(X) ((X) != (X))
+
 /* Py_IS_INFINITY(X)
  * Return 1 if float or double arg is an infinity, else 0.
  * Caution:
===================================================================
RCS file: Objects/floatobject.c,v
retrieving revision 2.3.3.0
diff -pu -r2.3.3.0 Objects/floatobject.c
--- Objects/floatobject.c	2003/06/28 20:04:24	2.3.3.0
+++ Objects/floatobject.c	2004/02/19 06:03:37
@@ -367,7 +367,21 @@ float_compare(PyFloatObject *v, PyFloatO
 {
 	double i = v->ob_fval;
 	double j = w->ob_fval;
-	return (i < j) ? -1 : (i > j) ? 1 : 0;
+	int c;
+	/* Because of NaNs IEEE arithmetic is not a total order.
+	 * Python works better with total orders, so use the same
+	 * total order that GNU sort does: NaNs sort before numbers,
+	 * and NaNs are sorted by internal bit-pattern.
+	 */
+	return ((i < j) ? -1
+		: (i > j) ? 1
+		: (i == j) ? 0
+		: !Py_IS_NAN(j) ? -1 /* i is NaN, j is not */
+		: !Py_IS_NAN(i) ? 1  /* j is NAN, i is not */
+		: /* i and j are both NaNs; compare them bitwise */
+		  ((c = memcmp(&v->ob_fval, &w->ob_fval, sizeof(v->ob_fval)))
+		   < 0) ? -1
+		: (c > 0));
 }
 
 static long


----------------------------------------------------------------------

Comment By: Michael Hudson (mwh)
Date: 2004-02-18 17:46

Message:
Logged In: YES 
user_id=6656

Man, that's strange (I see the same behaviour on my redhat 9
box with 2.3.3).

I don't have time to dig right now, but if you want to,
playing with equivalent C programs would be a very good start.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=899109&group_id=5470



More information about the Python-bugs-list mailing list