Mercurial > hg > octave-nkf > gnulib-hg
changeset 10287:7a5cfea8469f
Add isinf module.
author | Ben Pfaff <blp@cs.stanford.edu> |
---|---|
date | Wed, 23 Jul 2008 21:48:35 -0700 |
parents | 12944217dba7 |
children | 8f436125a451 |
files | ChangeLog MODULES.html.sh doc/posix-functions/isinf.texi lib/isinf.c lib/math.in.h m4/isinf.m4 m4/math_h.m4 modules/isinf modules/isinf-tests modules/math tests/test-isinf.c |
diffstat | 11 files changed, 424 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2008-07-14 Ben Pfaff <blp@gnu.org> + + Add isinf module. + * lib/isinf.c: New file. + * lib/math.in.h: Define isinf macro if we have decided to replace + it. + * m4/isinf.m4: New file. + * m4/math_h.m4: Initialize and substitute variables for isinf + module. + * modules/isinf: New file. + * modules/isinf-tests: New file. + * modules/math: Add substitutions for new module. + * tests/test-isinf.c: New file. + * doc/posix-functions/isinf.texi: Mention new module. + * MODULES.html.sh: Mention new module. + 2008-07-14 Ben Pfaff <blp@gnu.org> Factor out some macros for use by additional modules.
--- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -2000,6 +2000,7 @@ func_module frexpl func_module frexpl-nolibm func_module isfinite + func_module isinf func_module isnan func_module isnanf func_module isnanf-nolibm
--- a/doc/posix-functions/isinf.texi +++ b/doc/posix-functions/isinf.texi @@ -4,15 +4,15 @@ POSIX specification: @url{http://www.opengroup.org/susv3xsh/isinf.html} -Gnulib module: --- +Gnulib module: isinf Portability problems fixed by Gnulib: @itemize +@item +This macro is missing on some platforms: +AIX 4.3.2, IRIX 6.5, OSF/1 5.1, Solaris 10. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on some platforms: -AIX 4.3.2, IRIX 6.5, OSF/1 5.1, Solaris 10. @end itemize
new file mode 100644 --- /dev/null +++ b/lib/isinf.c @@ -0,0 +1,37 @@ +/* Test for positive or negative infinity. + Copyright (C) 2007-2008 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Ben Pfaff <blp@gnu.org>, 2008. */ + +#include <config.h> + +#include <float.h> + +int gl_isinff (float x) +{ + return x < -FLT_MAX || x > FLT_MAX; +} + +int gl_isinfd (double x) +{ + return x < -DBL_MAX || x > DBL_MAX; +} + +int gl_isinfl (long double x) +{ + return x < -LDBL_MAX || x > LDBL_MAX; +}
--- a/lib/math.in.h +++ b/lib/math.in.h @@ -381,6 +381,22 @@ #endif +#if @GNULIB_ISINF@ +# if @REPLACE_ISINF@ +extern int gl_isinff (float x); +extern int gl_isinfd (double x); +extern int gl_isinfl (long double x); +# undef isinf +# define isinf(x) \ + (sizeof (x) == sizeof (long double) ? gl_isinfl (x) : \ + sizeof (x) == sizeof (double) ? gl_isinfd (x) : \ + gl_isinff (x)) +# endif +#elif defined GNULIB_POSIXCHECK + /* How to override a macro? */ +#endif + + #if @GNULIB_ISNAN@ # if @REPLACE_ISNAN@ /* We can't just use the isnanf macro (e.g.) as exposed by
new file mode 100644 --- /dev/null +++ b/m4/isinf.m4 @@ -0,0 +1,49 @@ +# isinf.m4 serial 1 +dnl Copyright (C) 2007-2008 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_ISINF], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + dnl Persuade glibc <math.h> to declare isinf. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_CHECK_DECLS([isinf], , , [#include <math.h>]) + if test "$ac_cv_have_decl_isinf" = yes; then + gl_CHECK_MATH_LIB([ISINF_LIBM], [x = isinf (x);]) + if test "$ISINF_LIBM" != missing; then + dnl Test whether isinf() on 'long double' works. + gl_ISINFL_WORKS + case "$gl_cv_func_isinfl_works" in + *yes) ;; + *) ISINF_LIBM=missing;; + esac + fi + fi + if test "$ac_cv_have_decl_isinf" != yes || + test "$ISINF_LIBM" = missing; then + REPLACE_ISINF=1 + AC_LIBOBJ([isinf]) + ISINF_LIBM= + fi + AC_SUBST([REPLACE_ISINF]) + AC_SUBST([ISINF_LIBM]) +]) + +dnl Test whether isinf() correctly returns false for LDBL_MAX. +AC_DEFUN([gl_ISINFL_WORKS], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_C_BIGENDIAN]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether isinf(long double) works], [gl_cv_func_isinfl_works], + [ + AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <float.h> + #include <math.h>]], + [[return !!isinf(LDBL_MAX);]])], + [gl_cv_func_isinfl_works=yes], + [gl_cv_func_isinfl_works=no], + [gl_cv_func_isinfl_works="guessing no"]) + ]) +])
--- a/m4/math_h.m4 +++ b/m4/math_h.m4 @@ -51,6 +51,7 @@ GNULIB_FREXP=0; AC_SUBST([GNULIB_FREXP]) GNULIB_FREXPL=0; AC_SUBST([GNULIB_FREXPL]) GNULIB_ISFINITE=0; AC_SUBST([GNULIB_ISFINITE]) + GNULIB_ISINF=0; AC_SUBST([GNULIB_ISINF]) GNULIB_ISNAN=0; AC_SUBST([GNULIB_ISNAN]) GNULIB_LDEXPL=0; AC_SUBST([GNULIB_LDEXPL]) GNULIB_MATHL=0; AC_SUBST([GNULIB_MATHL]) @@ -83,6 +84,7 @@ REPLACE_FREXPL=0; AC_SUBST([REPLACE_FREXPL]) REPLACE_HUGE_VAL=0; AC_SUBST([REPLACE_HUGE_VAL]) REPLACE_ISFINITE=0; AC_SUBST([REPLACE_ISFINITE]) + REPLACE_ISINF=0; AC_SUBST([REPLACE_ISINF]) REPLACE_ISNAN=0; AC_SUBST([REPLACE_ISNAN]) REPLACE_LDEXPL=0; AC_SUBST([REPLACE_LDEXPL]) REPLACE_NAN=0; AC_SUBST([REPLACE_NAN])
new file mode 100644 --- /dev/null +++ b/modules/isinf @@ -0,0 +1,27 @@ +Description: +isinf macro: test for positive or negative infinity + +Files: +lib/isinf.c +m4/isinf.m4 +m4/check-math-lib.m4 + +Depends-on: +float +math +extensions + +configure.ac: +gl_ISINF +gl_MATH_MODULE_INDICATOR([isinf]) + +Makefile.am: + +Include: +<math.h> + +License: +GPL + +Maintainer: +Ben Pfaff
new file mode 100644 --- /dev/null +++ b/modules/isinf-tests @@ -0,0 +1,21 @@ +Files: +m4/exponentf.m4 +m4/exponentd.m4 +m4/exponentl.m4 +tests/test-isinf.c + +Depends-on: +float + +configure.ac: +gl_FLOAT_EXPONENT_LOCATION +gl_DOUBLE_EXPONENT_LOCATION +gl_LONG_DOUBLE_EXPONENT_LOCATION + +Makefile.am: +TESTS += test-isinf +check_PROGRAMS += test-isinf +test_isinf_LDADD = $(LDADD) @ISINF_LIBM@ + +License: +GPL
--- a/modules/math +++ b/modules/math @@ -29,6 +29,7 @@ -e 's|@''GNULIB_FREXP''@|$(GNULIB_FREXP)|g' \ -e 's|@''GNULIB_FREXPL''@|$(GNULIB_FREXPL)|g' \ -e 's|@''GNULIB_ISFINITE''@|$(GNULIB_ISFINITE)|g' \ + -e 's|@''GNULIB_ISINF''@|$(GNULIB_ISINF)|g' \ -e 's|@''GNULIB_ISNAN''@|$(GNULIB_ISNAN)|g' \ -e 's|@''GNULIB_LDEXPL''@|$(GNULIB_LDEXPL)|g' \ -e 's|@''GNULIB_MATHL''@|$(GNULIB_MATHL)|g' \ @@ -60,6 +61,7 @@ -e 's|@''REPLACE_FREXPL''@|$(REPLACE_FREXPL)|g' \ -e 's|@''REPLACE_HUGE_VAL''@|$(REPLACE_HUGE_VAL)|g' \ -e 's|@''REPLACE_ISFINITE''@|$(REPLACE_ISFINITE)|g' \ + -e 's|@''REPLACE_ISINF''@|$(REPLACE_ISINF)|g' \ -e 's|@''REPLACE_ISNAN''@|$(REPLACE_ISNAN)|g' \ -e 's|@''REPLACE_LDEXPL''@|$(REPLACE_LDEXPL)|g' \ -e 's|@''REPLACE_NAN''@|$(REPLACE_NAN)|g' \
new file mode 100644 --- /dev/null +++ b/tests/test-isinf.c @@ -0,0 +1,249 @@ +/* Test of isinf() substitute. + Copyright (C) 2007-2008 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Written by Ben Pfaff, 2008, using Bruno Haible's code as a + template. */ + +#include <config.h> + +#include <float.h> +#include <limits.h> +#include <math.h> + +#include <stdio.h> +#include <stdlib.h> + +#define ASSERT(expr) \ + do \ + { \ + if (!(expr)) \ + { \ + fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ + fflush (stderr); \ + abort (); \ + } \ + } \ + while (0) + +float zerof = 0.0f; +double zerod = 0.0; +long double zerol = 0.0L; + +static void +test_isinff () +{ + /* Zero. */ + ASSERT (!isinf (0.0f)); + /* Subnormal values. */ + ASSERT (!isinf (FLT_MIN / 2)); + ASSERT (!isinf (-FLT_MIN / 2)); + /* Finite values. */ + ASSERT (!isinf (3.141f)); + ASSERT (!isinf (3.141e30f)); + ASSERT (!isinf (3.141e-30f)); + ASSERT (!isinf (-2.718f)); + ASSERT (!isinf (-2.718e30f)); + ASSERT (!isinf (-2.718e-30f)); + ASSERT (!isinf (FLT_MAX)); + ASSERT (!isinf (-FLT_MAX)); + /* Infinite values. */ + ASSERT (isinf (1.0f / 0.0f)); + ASSERT (isinf (-1.0f / 0.0f)); + /* Quiet NaN. */ + ASSERT (!isinf (zerof / zerof)); +#if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT + /* Signalling NaN. */ + { + #define NWORDS \ + ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) + typedef union { float value; unsigned int word[NWORDS]; } memory_float; + memory_float m; + m.value = zerof / zerof; +# if FLT_EXPBIT0_BIT > 0 + m.word[FLT_EXPBIT0_WORD] ^= (unsigned int) 1 << (FLT_EXPBIT0_BIT - 1); +# else + m.word[FLT_EXPBIT0_WORD + (FLT_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)] + ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1); +# endif + if (FLT_EXPBIT0_WORD < NWORDS / 2) + m.word[FLT_EXPBIT0_WORD + 1] |= (unsigned int) 1 << FLT_EXPBIT0_BIT; + else + m.word[0] |= (unsigned int) 1; + ASSERT (!isinf (m.value)); + #undef NWORDS + } +#endif +} + +static void +test_isinfd () +{ + /* Zero. */ + ASSERT (!isinf (0.0)); + /* Subnormal values. */ + ASSERT (!isinf (DBL_MIN / 2)); + ASSERT (!isinf (-DBL_MIN / 2)); + /* Finite values. */ + ASSERT (!isinf (3.141)); + ASSERT (!isinf (3.141e30)); + ASSERT (!isinf (3.141e-30)); + ASSERT (!isinf (-2.718)); + ASSERT (!isinf (-2.718e30)); + ASSERT (!isinf (-2.718e-30)); + ASSERT (!isinf (DBL_MAX)); + ASSERT (!isinf (-DBL_MAX)); + /* Infinite values. */ + ASSERT (isinf (1.0 / 0.0)); + ASSERT (isinf (-1.0 / 0.0)); + /* Quiet NaN. */ + ASSERT (!isinf (zerod / zerod)); +#if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT + /* Signalling NaN. */ + { + #define NWORDS \ + ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) + typedef union { double value; unsigned int word[NWORDS]; } memory_double; + memory_double m; + m.value = zerod / zerod; +# if DBL_EXPBIT0_BIT > 0 + m.word[DBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (DBL_EXPBIT0_BIT - 1); +# else + m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)] + ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1); +# endif + m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)] + |= (unsigned int) 1 << DBL_EXPBIT0_BIT; + ASSERT (!isinf (m.value)); + #undef NWORDS + } +#endif +} + +static void +test_isinfl () +{ + #define NWORDS \ + ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) + typedef union { unsigned int word[NWORDS]; long double value; } + memory_long_double; + + /* Zero. */ + ASSERT (!isinf (0.0L)); + /* Subnormal values. */ + ASSERT (!isinf (LDBL_MIN / 2)); + ASSERT (!isinf (-LDBL_MIN / 2)); + /* Finite values. */ + ASSERT (!isinf (3.141L)); + ASSERT (!isinf (3.141e30L)); + ASSERT (!isinf (3.141e-30L)); + ASSERT (!isinf (-2.718L)); + ASSERT (!isinf (-2.718e30L)); + ASSERT (!isinf (-2.718e-30L)); + ASSERT (!isinf (LDBL_MAX)); + ASSERT (!isinf (-LDBL_MAX)); + /* Infinite values. */ + ASSERT (isinf (1.0L / 0.0L)); + ASSERT (isinf (-1.0L / 0.0L)); + /* Quiet NaN. */ + ASSERT (!isinf (zerol / zerol)); + +#if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT + /* A bit pattern that is different from a Quiet NaN. With a bit of luck, + it's a Signalling NaN. */ + { + memory_long_double m; + m.value = zerol / zerol; +# if LDBL_EXPBIT0_BIT > 0 + m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 1); +# else + m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)] + ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1); +# endif + m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)] + |= (unsigned int) 1 << LDBL_EXPBIT0_BIT; + ASSERT (!isinf (m.value)); + } +#endif + +#if ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) +/* Representation of an 80-bit 'long double' as an initializer for a sequence + of 'unsigned int' words. */ +# ifdef WORDS_BIGENDIAN +# define LDBL80_WORDS(exponent,manthi,mantlo) \ + { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \ + ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \ + (unsigned int) (mantlo) << 16 \ + } +# else +# define LDBL80_WORDS(exponent,manthi,mantlo) \ + { mantlo, manthi, exponent } +# endif + { /* Quiet NaN. */ + static memory_long_double x = + { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) }; + ASSERT (!isinf (x.value)); + } + { + /* Signalling NaN. */ + static memory_long_double x = + { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) }; + ASSERT (!isinf (x.value)); + } + /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities, + Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in + Intel IA-64 Architecture Software Developer's Manual, Volume 1: + Application Architecture. + Table 5-2 "Floating-Point Register Encodings" + Figure 5-6 "Memory to Floating-Point Register Data Translation" + */ + { /* Pseudo-NaN. */ + static memory_long_double x = + { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) }; + ASSERT (!isinf (x.value)); + } + { /* Pseudo-Infinity. */ + static memory_long_double x = + { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) }; + ASSERT (!isinf (x.value)); + } + { /* Pseudo-Zero. */ + static memory_long_double x = + { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) }; + ASSERT (!isinf (x.value)); + } + { /* Unnormalized number. */ + static memory_long_double x = + { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) }; + ASSERT (!isinf (x.value)); + } + { /* Pseudo-Denormal. */ + static memory_long_double x = + { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) }; + ASSERT (!isinf (x.value)); + } +#endif + + #undef NWORDS +} + +int +main () +{ + test_isinff (); + test_isinfd (); + test_isinfl (); + return 0; +}