1# frexp.m4 serial 16
2dnl Copyright (C) 2007-2020 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_DECLS_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_DECL_ALARM
105# include <signal.h>
106# include <unistd.h>
107#endif
108/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
109   ICC 10.0 has a bug when optimizing the expression -zero.
110   The expression -DBL_MIN * DBL_MIN does not work when cross-compiling
111   to PowerPC on Mac OS X 10.5.  */
112#if defined __hpux || defined __sgi || defined __ICC
113static double
114compute_minus_zero (void)
115{
116  return -DBL_MIN * DBL_MIN;
117}
118# define minus_zero compute_minus_zero ()
119#else
120double minus_zero = -0.0;
121#endif
122int main()
123{
124  int result = 0;
125  int i;
126  volatile double x;
127  double zero = 0.0;
128#if HAVE_DECL_ALARM
129  /* NeXTstep 3.3 frexp() runs into an endless loop when called on an infinite
130     number.  Let the test fail in this case.  */
131  signal (SIGALRM, SIG_DFL);
132  alarm (5);
133#endif
134  /* Test on denormalized numbers.  */
135  for (i = 1, x = 1.0; i >= DBL_MIN_EXP; i--, x *= 0.5)
136    ;
137  if (x > 0.0)
138    {
139      int exp;
140      double y = frexp (x, &exp);
141      /* On machines with IEEE754 arithmetic: x = 1.11254e-308, exp = -1022.
142         On NetBSD: y = 0.75. Correct: y = 0.5.  */
143      if (y != 0.5)
144        result |= 1;
145    }
146  /* Test on infinite numbers.  */
147  x = 1.0 / zero;
148  {
149    int exp;
150    double y = frexp (x, &exp);
151    if (y != x)
152      result |= 2;
153  }
154  /* Test on negative zero.  */
155  x = minus_zero;
156  {
157    int exp;
158    double y = frexp (x, &exp);
159    if (memcmp (&y, &x, sizeof x))
160      result |= 4;
161  }
162  return result;
163}]])],
164        [gl_cv_func_frexp_works=yes],
165        [gl_cv_func_frexp_works=no],
166        [case "$host_os" in
167           netbsd* | irix*) gl_cv_func_frexp_works="guessing no" ;;
168           mingw*) # Guess yes with MSVC, no with mingw.
169             AC_EGREP_CPP([Good], [
170#ifdef _MSC_VER
171 Good
172#endif
173               ],
174               [gl_cv_func_frexp_works="guessing yes"],
175               [gl_cv_func_frexp_works="guessing no"])
176             ;;
177           *) gl_cv_func_frexp_works="guessing yes" ;;
178         esac
179        ])
180    ])
181])
182