# [Numpy-discussion] isnan and co: cleaning up

David Cournapeau david@ar.media.kyoto-u.ac...
Fri Sep 5 00:06:07 CDT 2008

```Hi,

While working on my branch to clean the math configuration, I
noticed that the code for isnan and co became quite convoluted. autoconf
info file has a mention of it, and suggests the following for
portability (section 5.5.1 of autoconf):

The C99 standard says that `isinf' and `isnan' are macros.  On
some systems just macros are available (e.g., HP-UX and Solaris
10), on some systems both macros and functions (e.g., glibc
2.3.2), and on some systems only functions (e.g., IRIX 6 and
Solaris 9).  In some cases these functions are declared in
nonstandard headers like `<sunmath.h>' and defined in non-default
libraries like `-lm' or `-lsunmath'.

The C99 `isinf' and `isnan' macros work correctly with `long
double' arguments, but pre-C99 systems that use functions
typically assume `double' arguments.  On such a system, `isinf'
incorrectly returns true for a finite `long double' argument that
is outside the range of `double'.

To work around this porting mess, you can use code like the
following.

#include <math.h>

#ifndef isnan
# define isnan(x) \
(sizeof (x) == sizeof (long double) ? isnan_ld (x) \
: sizeof (x) == sizeof (double) ? isnan_d (x) \
: isnan_f (x))
static inline int isnan_f  (float       x) { return x != x; }
static inline int isnan_d  (double      x) { return x != x; }
static inline int isnan_ld (long double x) { return x != x; }
#endif

#ifndef isinf
# define isinf(x) \
(sizeof (x) == sizeof (long double) ? isinf_ld (x) \
: sizeof (x) == sizeof (double) ? isinf_d (x) \
: isinf_f (x))
static inline int isinf_f  (float       x) { return isnan (x -
x); }
static inline int isinf_d  (double      x) { return isnan (x -
x); }
static inline int isinf_ld (long double x) { return isnan (x -
x); }
#endif

Use `AC_C_INLINE' (*note C Compiler::) so that this code works on
compilers that lack the `inline' keyword.  Some optimizing
compilers mishandle these definitions, but systems with that bug
typically have missing or broken `isnan' functions anyway, so it's

This is simpler than the current code (I actually understand what the
above case does; the current code in numpy has many cases which I do not
understand), does not need any C code (_isnan and co), and probably more
portable since autoconf has a lot of experience there. Is the code in
_isnan really better than just relying on the nan property x != x ? (Do
we support platforms without a IEE754 FPU ?)

Does anyone has any thought on replacing the current code by the above
(modulo the inline part, which we can drop for now) ?

cheers,

David
```