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

Charles R Harris charlesr.harris@gmail....
Fri Sep 5 18:38:39 CDT 2008

On Thu, Sep 4, 2008 at 11:06 PM, David Cournapeau <
david@ar.media.kyoto-u.ac.jp> wrote:

> 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
>     probably not worth worrying about.
>
> 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) ?
>

+1, but (putting on pedant hat) I think the functions should be formatted in
the way revealed to us by K&R.

Chuck
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://projects.scipy.org/pipermail/numpy-discussion/attachments/20080905/01630c0a/attachment.html