diff options
author | Mark H Weaver <mhw@netris.org> | 2013-08-06 17:16:04 -0400 |
---|---|---|
committer | Mark H Weaver <mhw@netris.org> | 2013-08-06 17:16:04 -0400 |
commit | 524140436fc03ee439d5c358c8c7a4c2c559684a (patch) | |
tree | 0b79a3f02c6fac4f3f3071f6d4e0eb93b93843dd /lib | |
parent | ca7b6f6869072a79175c2d2db1b63f706bdf9b25 (diff) |
Add files from 'copysign' and 'isfinite' Gnulib modules.
* lib/copysign.c:
* lib/isfinite.c:
* lib/isnanf-nolibm.h:
* lib/isnanl-nolibm.h:
* lib/signbitd.c:
* lib/signbitf.c:
* lib/signbitl.c:
* m4/copysign.m4:
* m4/isfinite.m4:
* m4/signbit.m4: New files.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/copysign.c | 26 | ||||
-rw-r--r-- | lib/isfinite.c | 51 | ||||
-rw-r--r-- | lib/isnanf-nolibm.h | 40 | ||||
-rw-r--r-- | lib/isnanl-nolibm.h | 33 | ||||
-rw-r--r-- | lib/signbitd.c | 64 | ||||
-rw-r--r-- | lib/signbitf.c | 64 | ||||
-rw-r--r-- | lib/signbitl.c | 64 |
7 files changed, 342 insertions, 0 deletions
diff --git a/lib/copysign.c b/lib/copysign.c new file mode 100644 index 000000000..61efeb8de --- /dev/null +++ b/lib/copysign.c @@ -0,0 +1,26 @@ +/* Copy sign into another 'double' number. + Copyright (C) 2011-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <math.h> + +double +copysign (double x, double y) +{ + return (signbit (x) != signbit (y) ? - x : x); +} diff --git a/lib/isfinite.c b/lib/isfinite.c new file mode 100644 index 000000000..d9eddf54b --- /dev/null +++ b/lib/isfinite.c @@ -0,0 +1,51 @@ +/* Test for finite value (zero, subnormal, or normal, and not infinite or NaN). + Copyright (C) 2007-2013 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, see <http://www.gnu.org/licenses/>. */ + +/* Written by Ben Pfaff <blp@gnu.org>, 2007. */ + +#include <config.h> + +#include "isnanf-nolibm.h" +#include "isnand-nolibm.h" +#include "isnanl-nolibm.h" + +/* The "cc" compiler on HP-UX 11.11, when optimizing, simplifies the test + x - y == 0.0 to x == y, a simplification which is invalid when x and y + are Infinity. Disable this optimization. */ +#if defined __hpux && !defined __GNUC__ +static float zerof; +static double zerod; +static long double zerol; +#else +# define zerof 0.f +# define zerod 0. +# define zerol 0.L +#endif + +int gl_isfinitef (float x) +{ + return !isnanf (x) && x - x == zerof; +} + +int gl_isfinited (double x) +{ + return !isnand (x) && x - x == zerod; +} + +int gl_isfinitel (long double x) +{ + return !isnanl (x) && x - x == zerol; +} diff --git a/lib/isnanf-nolibm.h b/lib/isnanf-nolibm.h new file mode 100644 index 000000000..56f4fde61 --- /dev/null +++ b/lib/isnanf-nolibm.h @@ -0,0 +1,40 @@ +/* Test for NaN that does not need libm. + Copyright (C) 2007-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#if HAVE_ISNANF_IN_LIBC +/* Get declaration of isnan macro or (older) isnanf function. */ +# include <math.h> +# if __GNUC__ >= 4 + /* GCC 4.0 and newer provides three built-ins for isnan. */ +# undef isnanf +# define isnanf(x) __builtin_isnanf ((float)(x)) +# elif defined isnan +# undef isnanf +# define isnanf(x) isnan ((float)(x)) +# else + /* Get declaration of isnanf(), if not declared in <math.h>. */ +# if defined __sgi + /* We can't include <ieeefp.h>, because it conflicts with our definition of + isnand. Therefore declare isnanf separately. */ +extern int isnanf (float x); +# endif +# endif +#else +/* Test whether X is a NaN. */ +# undef isnanf +# define isnanf rpl_isnanf +extern int isnanf (float x); +#endif diff --git a/lib/isnanl-nolibm.h b/lib/isnanl-nolibm.h new file mode 100644 index 000000000..c5d0323b4 --- /dev/null +++ b/lib/isnanl-nolibm.h @@ -0,0 +1,33 @@ +/* Test for NaN that does not need libm. + Copyright (C) 2007-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#if HAVE_ISNANL_IN_LIBC +/* Get declaration of isnan macro or (older) isnanl function. */ +# include <math.h> +# if __GNUC__ >= 4 + /* GCC 4.0 and newer provides three built-ins for isnan. */ +# undef isnanl +# define isnanl(x) __builtin_isnanl ((long double)(x)) +# elif defined isnan +# undef isnanl +# define isnanl(x) isnan ((long double)(x)) +# endif +#else +/* Test whether X is a NaN. */ +# undef isnanl +# define isnanl rpl_isnanl +extern int isnanl (long double x); +#endif diff --git a/lib/signbitd.c b/lib/signbitd.c new file mode 100644 index 000000000..1c813dabf --- /dev/null +++ b/lib/signbitd.c @@ -0,0 +1,64 @@ +/* signbit() macro: Determine the sign bit of a floating-point number. + Copyright (C) 2007-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <math.h> + +#include <string.h> +#include "isnand-nolibm.h" +#include "float+.h" + +#ifdef gl_signbitd_OPTIMIZED_MACRO +# undef gl_signbitd +#endif + +int +gl_signbitd (double arg) +{ +#if defined DBL_SIGNBIT_WORD && defined DBL_SIGNBIT_BIT + /* The use of a union to extract the bits of the representation of a + 'long double' is safe in practice, despite of the "aliasing rules" of + C99, because the GCC docs say + "Even with '-fstrict-aliasing', type-punning is allowed, provided the + memory is accessed through the union type." + and similarly for other compilers. */ +# define NWORDS \ + ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) + union { double value; unsigned int word[NWORDS]; } m; + m.value = arg; + return (m.word[DBL_SIGNBIT_WORD] >> DBL_SIGNBIT_BIT) & 1; +#elif HAVE_COPYSIGN_IN_LIBC + return copysign (1.0, arg) < 0; +#else + /* This does not do the right thing for NaN, but this is irrelevant for + most use cases. */ + if (isnand (arg)) + return 0; + if (arg < 0.0) + return 1; + else if (arg == 0.0) + { + /* Distinguish 0.0 and -0.0. */ + static double plus_zero = 0.0; + double arg_mem = arg; + return (memcmp (&plus_zero, &arg_mem, SIZEOF_DBL) != 0); + } + else + return 0; +#endif +} diff --git a/lib/signbitf.c b/lib/signbitf.c new file mode 100644 index 000000000..817484b8f --- /dev/null +++ b/lib/signbitf.c @@ -0,0 +1,64 @@ +/* signbit() macro: Determine the sign bit of a floating-point number. + Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <math.h> + +#include <string.h> +#include "isnanf-nolibm.h" +#include "float+.h" + +#ifdef gl_signbitf_OPTIMIZED_MACRO +# undef gl_signbitf +#endif + +int +gl_signbitf (float arg) +{ +#if defined FLT_SIGNBIT_WORD && defined FLT_SIGNBIT_BIT + /* The use of a union to extract the bits of the representation of a + 'long double' is safe in practice, despite of the "aliasing rules" of + C99, because the GCC docs say + "Even with '-fstrict-aliasing', type-punning is allowed, provided the + memory is accessed through the union type." + and similarly for other compilers. */ +# define NWORDS \ + ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) + union { float value; unsigned int word[NWORDS]; } m; + m.value = arg; + return (m.word[FLT_SIGNBIT_WORD] >> FLT_SIGNBIT_BIT) & 1; +#elif HAVE_COPYSIGNF_IN_LIBC + return copysignf (1.0f, arg) < 0; +#else + /* This does not do the right thing for NaN, but this is irrelevant for + most use cases. */ + if (isnanf (arg)) + return 0; + if (arg < 0.0f) + return 1; + else if (arg == 0.0f) + { + /* Distinguish 0.0f and -0.0f. */ + static float plus_zero = 0.0f; + float arg_mem = arg; + return (memcmp (&plus_zero, &arg_mem, SIZEOF_FLT) != 0); + } + else + return 0; +#endif +} diff --git a/lib/signbitl.c b/lib/signbitl.c new file mode 100644 index 000000000..159cfceb8 --- /dev/null +++ b/lib/signbitl.c @@ -0,0 +1,64 @@ +/* signbit() macro: Determine the sign bit of a floating-point number. + Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <math.h> + +#include <string.h> +#include "isnanl-nolibm.h" +#include "float+.h" + +#ifdef gl_signbitl_OPTIMIZED_MACRO +# undef gl_signbitl +#endif + +int +gl_signbitl (long double arg) +{ +#if defined LDBL_SIGNBIT_WORD && defined LDBL_SIGNBIT_BIT + /* The use of a union to extract the bits of the representation of a + 'long double' is safe in practice, despite of the "aliasing rules" of + C99, because the GCC docs say + "Even with '-fstrict-aliasing', type-punning is allowed, provided the + memory is accessed through the union type." + and similarly for other compilers. */ +# define NWORDS \ + ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) + union { long double value; unsigned int word[NWORDS]; } m; + m.value = arg; + return (m.word[LDBL_SIGNBIT_WORD] >> LDBL_SIGNBIT_BIT) & 1; +#elif HAVE_COPYSIGNL_IN_LIBC + return copysignl (1.0L, arg) < 0; +#else + /* This does not do the right thing for NaN, but this is irrelevant for + most use cases. */ + if (isnanl (arg)) + return 0; + if (arg < 0.0L) + return 1; + else if (arg == 0.0L) + { + /* Distinguish 0.0L and -0.0L. */ + static long double plus_zero = 0.0L; + long double arg_mem = arg; + return (memcmp (&plus_zero, &arg_mem, SIZEOF_LDBL) != 0); + } + else + return 0; +#endif +} |