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

SourceForge.net noreply at sourceforge.net
Thu Feb 19 01:39:00 EST 2004


Bugs item #899109, was opened at 2004-02-17 21:47
Message generated for change (Comment added) made by eggert
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: 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