+2007-04-10 Paul Eggert <eggert@cs.ucla.edu>
+ Bruno Haible <bruno@clisp.org>
+
+ * m4/signbit.m4 (gl_SIGNBIT): When the sign bit position could not
+ be determined, test for availability of the copysignf, copysign,
+ copysignl functions.
+ * lib/signbitf.c (gl_signbitf): Use copysignf if available in libc.
+ * lib/signbitd.c (gl_signbitd): Use copysign if available in libc.
+ * lib/signbitl.c (gl_signbitl): Use copysignl if available in libc.
+
2007-04-09 Eric Blake <ebb9@byu.net>
* lib/stdio_.h [REPLACE_FFLUSH]: Declare rpl_fflush.
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. */
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. */
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. */
-# signbit.m4 serial 1
+# signbit.m4 serial 2
dnl Copyright (C) 2007 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
gl_FLOAT_SIGN_LOCATION
gl_DOUBLE_SIGN_LOCATION
gl_LONG_DOUBLE_SIGN_LOCATION
+ if test "$gl_cv_cc_float_signbit" = unknown; then
+ dnl Test whether copysignf() is declared.
+ AC_CHECK_DECLS([copysignf], , , [#include <math.h>])
+ if test "$ac_cv_have_decl_copysignf" = yes; then
+ dnl Test whether copysignf() can be used without libm.
+ AC_CACHE_CHECK([whether copysignf can be used without linking with libm],
+ [gl_cv_func_copysignf_no_libm],
+ [
+ AC_TRY_LINK([#include <math.h>
+ float x, y;],
+ [return copysignf (x, y) < 0;],
+ [gl_cv_func_copysignf_no_libm=yes],
+ [gl_cv_func_copysignf_no_libm=no])
+ ])
+ if test $gl_cv_func_copysignf_no_libm = yes; then
+ AC_DEFINE([HAVE_COPYSIGNF_IN_LIBC], 1,
+ [Define if the copysignf function is declared in <math.h> and available in libc.])
+ fi
+ fi
+ fi
+ if test "$gl_cv_cc_double_signbit" = unknown; then
+ dnl Test whether copysign() is declared.
+ AC_CHECK_DECLS([copysign], , , [#include <math.h>])
+ if test "$ac_cv_have_decl_copysign" = yes; then
+ dnl Test whether copysign() can be used without libm.
+ AC_CACHE_CHECK([whether copysign can be used without linking with libm],
+ [gl_cv_func_copysign_no_libm],
+ [
+ AC_TRY_LINK([#include <math.h>
+ double x, y;],
+ [return copysign (x, y) < 0;],
+ [gl_cv_func_copysign_no_libm=yes],
+ [gl_cv_func_copysign_no_libm=no])
+ ])
+ if test $gl_cv_func_copysign_no_libm = yes; then
+ AC_DEFINE([HAVE_COPYSIGN_IN_LIBC], 1,
+ [Define if the copysign function is declared in <math.h> and available in libc.])
+ fi
+ fi
+ fi
+ if test "$gl_cv_cc_long_double_signbit" = unknown; then
+ dnl Test whether copysignl() is declared.
+ AC_CHECK_DECLS([copysignl], , , [#include <math.h>])
+ if test "$ac_cv_have_decl_copysignl" = yes; then
+ dnl Test whether copysignl() can be used without libm.
+ AC_CACHE_CHECK([whether copysignl can be used without linking with libm],
+ [gl_cv_func_copysignl_no_libm],
+ [
+ AC_TRY_LINK([#include <math.h>
+ long double x, y;],
+ [return copysignl (x, y) < 0;],
+ [gl_cv_func_copysignl_no_libm=yes],
+ [gl_cv_func_copysignl_no_libm=no])
+ ])
+ if test $gl_cv_func_copysignl_no_libm = yes; then
+ AC_DEFINE([HAVE_COPYSIGNL_IN_LIBC], 1,
+ [Define if the copysignl function is declared in <math.h> and available in libc.])
+ fi
+ fi
+ fi
fi
])