thouis / numpy-trac-migration

numpy Trac to github issues migration
2 stars 3 forks source link

isfinite, isinf macros raise invalid value fp error flag (Trac #1500) #5302

Open numpy-gitbot opened 12 years ago

numpy-gitbot commented 12 years ago

Original ticket http://projects.scipy.org/numpy/ticket/1500 on 2010-06-03 by atmention:efiring, assigned to unknown.

In npy_math.h, if NPY_HAVE_DECL_ISFINITE is not defined, the macro that is defined in place of a system-supplied macro works by generating a nan when given an inf, and then using isnan to detect that case. This raises the invalid value fp error flag, so every time numpy.isfinite encounters an inf, a warning is printed by default. The situation is the same with isinf. Here is the relevant code from npy_math.h:

#ifndef NPY_HAVE_DECL_ISFINITE
    #define npy_isfinite(x) !npy_isnan((x) + (-x))
#else
    #define npy_isfinite(x) isfinite((x))
#endif

#ifndef NPY_HAVE_DECL_ISINF
    #define npy_isinf(x) (!npy_isfinite(x) && !npy_isnan(x))
#else
    #define npy_isinf(x) isinf((x))
#endif 

The problem became evident because of a bug in setup.py: the NPY_HAVEDECL macros were not being generated. This was fixed in svn 8455, so now the problem will appear only on those (very rare?) platforms that do not have their own isinf and isfinite.

numpy-gitbot commented 12 years ago

atmention:pv wrote on 2010-07-15

This is probably the correct fix:

--- a/numpy/core/include/numpy/npy_math.h
+++ b/numpy/core/include/numpy/npy_math.h
atmention:atmention: -150,16 +150,16 atmention:atmention: double npy_spacing(double x);
     #define npy_isnan(x) isnan((x))
 #endif

-#ifndef NPY_HAVE_DECL_ISFINITE
-    #define npy_isfinite(x) !npy_isnan((x) + (-x))
+#ifndef NPY_HAVE_DECL_ISINF
+    #define npy_isinf(x) ((x) == NPY_INFINITY || (x) == -NPY_INFINITY)
 #else
-    #define npy_isfinite(x) isfinite((x))
+    #define npy_isinf(x) isinf((x))
 #endif

-#ifndef NPY_HAVE_DECL_ISINF
-    #define npy_isinf(x) (!npy_isfinite(x) && !npy_isnan(x))
+#ifndef NPY_HAVE_DECL_ISFINITE
+    #define npy_isfinite(x) (!npy_isnan(x) && !npy_isinf(x))
 #else
-    #define npy_isinf(x) isinf((x))
+    #define npy_isfinite(x) isfinite((x))
 #endif

 #ifndef NPY_HAVE_DECL_SIGNBIT

I think it'll work across the different FP types, but will re-think about it tomorrow...