1# frexp.m4 serial 14
2dnl Copyright (C) 2007-2012 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7AC_DEFUN([gl_FUNC_FREXP],
8[
9  AC_REQUIRE([gl_MATH_H_DEFAULTS])
10  AC_REQUIRE([gl_CHECK_FREXP_NO_LIBM])
11  FREXP_LIBM=
12  if test $gl_cv_func_frexp_no_libm = no; then
13    AC_CACHE_CHECK([whether frexp() can be used with libm],
14      [gl_cv_func_frexp_in_libm],
15      [
16        save_LIBS="$LIBS"
17        LIBS="$LIBS -lm"
18        AC_LINK_IFELSE(
19          [AC_LANG_PROGRAM(
20             [[#include <math.h>
21               double x;]],
22             [[int e; return frexp (x, &e) > 0;]])],
23          [gl_cv_func_frexp_in_libm=yes],
24          [gl_cv_func_frexp_in_libm=no])
25        LIBS="$save_LIBS"
26      ])
27    if test $gl_cv_func_frexp_in_libm = yes; then
28      FREXP_LIBM=-lm
29    fi
30  fi
31  if test $gl_cv_func_frexp_no_libm = yes \
32     || test $gl_cv_func_frexp_in_libm = yes; then
33    save_LIBS="$LIBS"
34    LIBS="$LIBS $FREXP_LIBM"
35    gl_FUNC_FREXP_WORKS
36    LIBS="$save_LIBS"
37    case "$gl_cv_func_frexp_works" in
38      *yes) gl_func_frexp=yes ;;
39      *)    gl_func_frexp=no; REPLACE_FREXP=1; FREXP_LIBM= ;;
40    esac
41  else
42    gl_func_frexp=no
43  fi
44  if test $gl_func_frexp = yes; then
45    AC_DEFINE([HAVE_FREXP], [1],
46      [Define if the frexp() function is available and works.])
47  fi
48  AC_SUBST([FREXP_LIBM])
49])
50
51AC_DEFUN([gl_FUNC_FREXP_NO_LIBM],
52[
53  AC_REQUIRE([gl_MATH_H_DEFAULTS])
54  AC_REQUIRE([gl_CHECK_FREXP_NO_LIBM])
55  if test $gl_cv_func_frexp_no_libm = yes; then
56    gl_FUNC_FREXP_WORKS
57    case "$gl_cv_func_frexp_works" in
58      *yes) gl_func_frexp_no_libm=yes ;;
59      *)    gl_func_frexp_no_libm=no; REPLACE_FREXP=1 ;;
60    esac
61  else
62    gl_func_frexp_no_libm=no
63    dnl Set REPLACE_FREXP here because the system may have frexp in libm.
64    REPLACE_FREXP=1
65  fi
66  if test $gl_func_frexp_no_libm = yes; then
67    AC_DEFINE([HAVE_FREXP_IN_LIBC], [1],
68      [Define if the frexp() function is available in libc.])
69  fi
70])
71
72dnl Test whether frexp() can be used without linking with libm.
73dnl Set gl_cv_func_frexp_no_libm to 'yes' or 'no' accordingly.
74AC_DEFUN([gl_CHECK_FREXP_NO_LIBM],
75[
76  AC_CACHE_CHECK([whether frexp() can be used without linking with libm],
77    [gl_cv_func_frexp_no_libm],
78    [
79      AC_LINK_IFELSE(
80        [AC_LANG_PROGRAM(
81           [[#include <math.h>
82             double x;]],
83           [[int e; return frexp (x, &e) > 0;]])],
84        [gl_cv_func_frexp_no_libm=yes],
85        [gl_cv_func_frexp_no_libm=no])
86    ])
87])
88
89dnl Test whether frexp() works also on denormalized numbers (this fails e.g. on
90dnl NetBSD 3.0), on infinite numbers (this fails e.g. on IRIX 6.5 and mingw),
91dnl and on negative zero (this fails e.g. on NetBSD 4.99 and mingw).
92AC_DEFUN([gl_FUNC_FREXP_WORKS],
93[
94  AC_REQUIRE([AC_PROG_CC])
95  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
96  AC_CHECK_FUNCS_ONCE([alarm])
97  AC_CACHE_CHECK([whether frexp works], [gl_cv_func_frexp_works],
98    [
99      AC_RUN_IFELSE(
100        [AC_LANG_SOURCE([[
101#include <float.h>
102#include <math.h>
103#include <string.h>
104#if HAVE_ALARM
105# include <unistd.h>
106#endif
107/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
108   ICC 10.0 has a bug when optimizing the expression -zero.
109   The expression -DBL_MIN * DBL_MIN does not work when cross-compiling
110   to PowerPC on Mac OS X 10.5.  */
111#if defined __hpux || defined __sgi || defined __ICC
112static double
113compute_minus_zero (void)
114{
115  return -DBL_MIN * DBL_MIN;
116}
117# define minus_zero compute_minus_zero ()
118#else
119double minus_zero = -0.0;
120#endif
121int main()
122{
123  int result = 0;
124  int i;
125  volatile double x;
126  double zero = 0.0;
127#if HAVE_ALARM
128  /* NeXTstep 3.3 frexp() runs into an endless loop when called on an infinite
129     number.  Let the test fail in this case.  */
130  alarm (5);
131#endif
132  /* Test on denormalized numbers.  */
133  for (i = 1, x = 1.0; i >= DBL_MIN_EXP; i--, x *= 0.5)
134    ;
135  if (x > 0.0)
136    {
137      int exp;
138      double y = frexp (x, &exp);
139      /* On machines with IEEE754 arithmetic: x = 1.11254e-308, exp = -1022.
140         On NetBSD: y = 0.75. Correct: y = 0.5.  */
141      if (y != 0.5)
142        result |= 1;
143    }
144  /* Test on infinite numbers.  */
145  x = 1.0 / zero;
146  {
147    int exp;
148    double y = frexp (x, &exp);
149    if (y != x)
150      result |= 2;
151  }
152  /* Test on negative zero.  */
153  x = minus_zero;
154  {
155    int exp;
156    double y = frexp (x, &exp);
157    if (memcmp (&y, &x, sizeof x))
158      result |= 4;
159  }
160  return result;
161}]])],
162        [gl_cv_func_frexp_works=yes],
163        [gl_cv_func_frexp_works=no],
164        [case "$host_os" in
165           netbsd* | irix* | mingw*) gl_cv_func_frexp_works="guessing no";;
166           *)                        gl_cv_func_frexp_works="guessing yes";;
167         esac
168        ])
169    ])
170])
171