1# frexp.m4 serial 7
2dnl Copyright (C) 2007, 2008, 2009, 2010 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  FREXP_LIBM=
11  AC_CACHE_CHECK([whether frexp() can be used without linking with libm],
12    [gl_cv_func_frexp_no_libm],
13    [
14      AC_TRY_LINK([#include <math.h>
15                   double x;],
16                  [int e; return frexp (x, &e) > 0;],
17        [gl_cv_func_frexp_no_libm=yes],
18        [gl_cv_func_frexp_no_libm=no])
19    ])
20  if test $gl_cv_func_frexp_no_libm = no; then
21    AC_CACHE_CHECK([whether frexp() can be used with libm],
22      [gl_cv_func_frexp_in_libm],
23      [
24        save_LIBS="$LIBS"
25        LIBS="$LIBS -lm"
26        AC_TRY_LINK([#include <math.h>
27                     double x;],
28                    [int e; return frexp (x, &e) > 0;],
29          [gl_cv_func_frexp_in_libm=yes],
30          [gl_cv_func_frexp_in_libm=no])
31        LIBS="$save_LIBS"
32      ])
33    if test $gl_cv_func_frexp_in_libm = yes; then
34      FREXP_LIBM=-lm
35    fi
36  fi
37  if test $gl_cv_func_frexp_no_libm = yes \
38     || test $gl_cv_func_frexp_in_libm = yes; then
39    save_LIBS="$LIBS"
40    LIBS="$LIBS $FREXP_LIBM"
41    gl_FUNC_FREXP_WORKS
42    LIBS="$save_LIBS"
43    case "$gl_cv_func_frexp_works" in
44      *yes) gl_func_frexp=yes ;;
45      *)    gl_func_frexp=no; REPLACE_FREXP=1; FREXP_LIBM= ;;
46    esac
47  else
48    gl_func_frexp=no
49  fi
50  if test $gl_func_frexp = yes; then
51    AC_DEFINE([HAVE_FREXP], [1],
52      [Define if the frexp() function is available and works.])
53  else
54    AC_LIBOBJ([frexp])
55  fi
56  AC_SUBST([FREXP_LIBM])
57])
58
59AC_DEFUN([gl_FUNC_FREXP_NO_LIBM],
60[
61  AC_REQUIRE([gl_MATH_H_DEFAULTS])
62  AC_CACHE_CHECK([whether frexp() can be used without linking with libm],
63    [gl_cv_func_frexp_no_libm],
64    [
65      AC_TRY_LINK([#include <math.h>
66                   double x;],
67                  [int e; return frexp (x, &e) > 0;],
68        [gl_cv_func_frexp_no_libm=yes],
69        [gl_cv_func_frexp_no_libm=no])
70    ])
71  if test $gl_cv_func_frexp_no_libm = yes; then
72    gl_FUNC_FREXP_WORKS
73    case "$gl_cv_func_frexp_works" in
74      *yes) gl_func_frexp_no_libm=yes ;;
75      *)    gl_func_frexp_no_libm=no; REPLACE_FREXP=1 ;;
76    esac
77  else
78    gl_func_frexp_no_libm=no
79    dnl Set REPLACE_FREXP here because the system may have frexp in libm.
80    REPLACE_FREXP=1
81  fi
82  if test $gl_func_frexp_no_libm = yes; then
83    AC_DEFINE([HAVE_FREXP_IN_LIBC], [1],
84      [Define if the frexp() function is available in libc.])
85  else
86    AC_LIBOBJ([frexp])
87  fi
88])
89
90dnl Test whether frexp() works also on denormalized numbers (this fails e.g. on
91dnl NetBSD 3.0), on infinite numbers (this fails e.g. on IRIX 6.5 and mingw),
92dnl and on negative zero (this fails e.g. on NetBSD 4.99).
93AC_DEFUN([gl_FUNC_FREXP_WORKS],
94[
95  AC_REQUIRE([AC_PROG_CC])
96  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
97  AC_CACHE_CHECK([whether frexp works], [gl_cv_func_frexp_works],
98    [
99      AC_TRY_RUN([
100#include <float.h>
101#include <math.h>
102#include <string.h>
103int main()
104{
105  int i;
106  volatile double x;
107/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
108   So we use -zero instead.  */
109  double zero = 0.0;
110  /* Test on denormalized numbers.  */
111  for (i = 1, x = 1.0; i >= DBL_MIN_EXP; i--, x *= 0.5)
112    ;
113  if (x > 0.0)
114    {
115      int exp;
116      double y = frexp (x, &exp);
117      /* On machines with IEEE754 arithmetic: x = 1.11254e-308, exp = -1022.
118         On NetBSD: y = 0.75. Correct: y = 0.5.  */
119      if (y != 0.5)
120        return 1;
121    }
122  /* Test on infinite numbers.  */
123  x = 1.0 / 0.0;
124  {
125    int exp;
126    double y = frexp (x, &exp);
127    if (y != x)
128      return 1;
129  }
130  /* Test on negative zero.  */
131  x = -zero;
132  {
133    int exp;
134    double y = frexp (x, &exp);
135    if (memcmp (&y, &x, sizeof x))
136      return 1;
137  }
138  return 0;
139}], [gl_cv_func_frexp_works=yes], [gl_cv_func_frexp_works=no],
140      [case "$host_os" in
141         netbsd* | irix* | mingw*) gl_cv_func_frexp_works="guessing no";;
142         *)                        gl_cv_func_frexp_works="guessing yes";;
143       esac
144      ])
145    ])
146])
147