On IRIX 6.5 and mingw, the system function frexpf() has some of the bugs that the frexp() also has. Here's the workaround:
2011-10-06 Bruno Haible <br...@clisp.org> frexpf: Work around problems on IRIX and mingw. * lib/math.in.h (frexpf): Consider also REPLACE_FREXPF. * m4/math_h.m4 (gl_MATH_H_DEFAULTS): Initialize REPLACE_FREXPF. * m4/frexpf.m4 (gl_FUNC_FREXPF_WORKS): New macro. (gl_FUNC_FREXPF): Invoke it. Set REPLACE_FREXPF. * modules/frexpf (Depends-on, configure.ac): Consider REPLACE_FREXPF. * modules/math (Makefile.am): Substitute REPLACE_FREXPF. * doc/posix-functions/frexpf.texi: Mention the IRIX and mingw problems. --- doc/posix-functions/frexpf.texi.orig Fri Oct 7 00:58:44 2011 +++ doc/posix-functions/frexpf.texi Thu Oct 6 22:46:47 2011 @@ -10,10 +10,16 @@ @itemize @item This function is missing on some platforms: -Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9. +Minix 3.1.8, AIX 5.1, HP-UX 11, Solaris 9. @item This function is only defined as a macro with arguments on some platforms: MSVC 9. +@item +This function does not work on negative zero on some platforms: +mingw. +@item +This function does not work on infinite numbers on some platforms: +IRIX 6.5, mingw. @end itemize Portability problems not fixed by Gnulib: --- lib/math.in.h.orig Fri Oct 7 00:58:44 2011 +++ lib/math.in.h Fri Oct 7 00:28:01 2011 @@ -343,11 +343,20 @@ If x is infinite or NaN: mantissa = x, exp unspecified. Store exp in *EXPPTR and return mantissa. */ #if @GNULIB_FREXPF@ -# if !@HAVE_FREXPF@ -# undef frexpf +# if @REPLACE_FREXPF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef frexpf +# define frexpf rpl_frexpf +# endif +_GL_FUNCDECL_RPL (frexpf, float, (float x, int *expptr) _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (frexpf, float, (float x, int *expptr)); +# else +# if !@HAVE_FREXPF@ +# undef frexpf _GL_FUNCDECL_SYS (frexpf, float, (float x, int *expptr) _GL_ARG_NONNULL ((2))); -# endif +# endif _GL_CXXALIAS_SYS (frexpf, float, (float x, int *expptr)); +# endif _GL_CXXALIASWARN (frexpf); #elif defined GNULIB_POSIXCHECK # undef frexpf --- m4/frexpf.m4.orig Fri Oct 7 00:58:44 2011 +++ m4/frexpf.m4 Fri Oct 7 00:56:43 2011 @@ -1,4 +1,4 @@ -# frexpf.m4 serial 2 +# frexpf.m4 serial 3 dnl Copyright (C) 2011 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -13,10 +13,81 @@ dnl exists, is defined in the same library as frexp(). This is not the case dnl on NetBSD, OpenBSD. gl_MATHFUNC([frexpf], [float], [(float, int *)]) - if test $gl_cv_func_frexpf_no_libm = no \ - && test $gl_cv_func_frexpf_in_libm = no; then + if test $gl_cv_func_frexpf_no_libm = yes \ + || test $gl_cv_func_frexpf_in_libm = yes; then + save_LIBS="$LIBS" + LIBS="$LIBS $FREXPF_LIBM" + gl_FUNC_FREXPF_WORKS + LIBS="$save_LIBS" + case "$gl_cv_func_frexpf_works" in + *yes) ;; + *) REPLACE_FREXPF=1 ;; + esac + else HAVE_FREXPF=0 + fi + if test $HAVE_FREXPF = 0 || test $REPLACE_FREXPF = 1; then FREXPF_LIBM="$FREXP_LIBM" fi AC_SUBST([FREXPF_LIBM]) ]) + +dnl Test whether frexpf() works also on infinite numbers (this fails e.g. on +dnl IRIX 6.5 and mingw) and on negative zero (this fails e.g. on mingw). +AC_DEFUN([gl_FUNC_FREXPF_WORKS], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether frexpf works], [gl_cv_func_frexpf_works], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include <float.h> +#include <math.h> +#include <string.h> +/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0. + ICC 10.0 has a bug when optimizing the expression -zero. + The expression -FLT_MIN * FLT_MIN does not work when cross-compiling + to PowerPC on MacOS X 10.5. */ +#if defined __hpux || defined __sgi || defined __ICC +static float +compute_minus_zero (void) +{ + return -FLT_MIN * FLT_MIN; +} +# define minus_zero compute_minus_zero () +#else +float minus_zero = -0.0f; +#endif +int main() +{ + int result = 0; + volatile float x; + float zero = 0.0f; + /* Test on infinite numbers. */ + x = 1.0f / zero; + { + int exp; + float y = frexpf (x, &exp); + if (y != x) + result |= 1; + } + /* Test on negative zero. */ + x = minus_zero; + { + int exp; + float y = frexpf (x, &exp); + if (memcmp (&y, &x, sizeof x)) + result |= 2; + } + return result; +}]])], + [gl_cv_func_frexpf_works=yes], + [gl_cv_func_frexpf_works=no], + [case "$host_os" in + irix* | mingw*) gl_cv_func_frexpf_works="guessing no";; + *) gl_cv_func_frexpf_works="guessing yes";; + esac + ]) + ]) +]) --- m4/math_h.m4.orig Fri Oct 7 00:58:44 2011 +++ m4/math_h.m4 Fri Oct 7 00:28:40 2011 @@ -1,4 +1,4 @@ -# math_h.m4 serial 29 +# math_h.m4 serial 30 dnl Copyright (C) 2007-2011 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -137,6 +137,7 @@ REPLACE_FLOOR=0; AC_SUBST([REPLACE_FLOOR]) REPLACE_FLOORF=0; AC_SUBST([REPLACE_FLOORF]) REPLACE_FLOORL=0; AC_SUBST([REPLACE_FLOORL]) + REPLACE_FREXPF=0; AC_SUBST([REPLACE_FREXPF]) REPLACE_FREXP=0; AC_SUBST([REPLACE_FREXP]) REPLACE_FREXPL=0; AC_SUBST([REPLACE_FREXPL]) REPLACE_HUGE_VAL=0; AC_SUBST([REPLACE_HUGE_VAL]) --- modules/frexpf.orig Fri Oct 7 00:58:44 2011 +++ modules/frexpf Fri Oct 7 00:30:12 2011 @@ -8,11 +8,11 @@ Depends-on: math -frexp [test $HAVE_FREXPF = 0] +frexp [test $HAVE_FREXPF = 0 || test $REPLACE_FREXPF = 1] configure.ac: gl_FUNC_FREXPF -if test $HAVE_FREXPF = 0; then +if test $HAVE_FREXPF = 0 || test $REPLACE_FREXPF = 1; then AC_LIBOBJ([frexpf]) fi gl_MATH_MODULE_INDICATOR([frexpf]) --- modules/math.orig Fri Oct 7 00:58:44 2011 +++ modules/math Fri Oct 7 00:29:02 2011 @@ -110,6 +110,7 @@ -e 's|@''REPLACE_FLOOR''@|$(REPLACE_FLOOR)|g' \ -e 's|@''REPLACE_FLOORF''@|$(REPLACE_FLOORF)|g' \ -e 's|@''REPLACE_FLOORL''@|$(REPLACE_FLOORL)|g' \ + -e 's|@''REPLACE_FREXPF''@|$(REPLACE_FREXPF)|g' \ -e 's|@''REPLACE_FREXP''@|$(REPLACE_FREXP)|g' \ -e 's|@''REPLACE_FREXPL''@|$(REPLACE_FREXPL)|g' \ -e 's|@''REPLACE_HUGE_VAL''@|$(REPLACE_HUGE_VAL)|g' \ -- In memoriam Bahriye Üçok <http://en.wikipedia.org/wiki/Bahriye_Üçok>