missed commit
[gnulib.git] / m4 / frexp.m4
1 # frexp.m4 serial 8
2 dnl Copyright (C) 2007-2010 Free Software Foundation, Inc.
3 dnl This file is free software; the Free Software Foundation
4 dnl gives unlimited permission to copy and/or distribute it,
5 dnl with or without modifications, as long as this notice is preserved.
6
7 AC_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_TRY_LINK([#include <math.h>
19                      double x;],
20                     [int e; return frexp (x, &e) > 0;],
21           [gl_cv_func_frexp_in_libm=yes],
22           [gl_cv_func_frexp_in_libm=no])
23         LIBS="$save_LIBS"
24       ])
25     if test $gl_cv_func_frexp_in_libm = yes; then
26       FREXP_LIBM=-lm
27     fi
28   fi
29   if test $gl_cv_func_frexp_no_libm = yes \
30      || test $gl_cv_func_frexp_in_libm = yes; then
31     save_LIBS="$LIBS"
32     LIBS="$LIBS $FREXP_LIBM"
33     gl_FUNC_FREXP_WORKS
34     LIBS="$save_LIBS"
35     case "$gl_cv_func_frexp_works" in
36       *yes) gl_func_frexp=yes ;;
37       *)    gl_func_frexp=no; REPLACE_FREXP=1; FREXP_LIBM= ;;
38     esac
39   else
40     gl_func_frexp=no
41   fi
42   if test $gl_func_frexp = yes; then
43     AC_DEFINE([HAVE_FREXP], [1],
44       [Define if the frexp() function is available and works.])
45   else
46     AC_LIBOBJ([frexp])
47   fi
48   AC_SUBST([FREXP_LIBM])
49 ])
50
51 AC_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   else
70     AC_LIBOBJ([frexp])
71   fi
72 ])
73
74 dnl Test whether frexp() can be used without linking with libm.
75 dnl Set gl_cv_func_frexp_no_libm to 'yes' or 'no' accordingly.
76 AC_DEFUN([gl_CHECK_FREXP_NO_LIBM],
77 [
78   AC_CACHE_CHECK([whether frexp() can be used without linking with libm],
79     [gl_cv_func_frexp_no_libm],
80     [
81       AC_TRY_LINK([#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
89 dnl Test whether frexp() works also on denormalized numbers (this fails e.g. on
90 dnl NetBSD 3.0), on infinite numbers (this fails e.g. on IRIX 6.5 and mingw),
91 dnl and on negative zero (this fails e.g. on NetBSD 4.99).
92 AC_DEFUN([gl_FUNC_FREXP_WORKS],
93 [
94   AC_REQUIRE([AC_PROG_CC])
95   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
96   AC_CACHE_CHECK([whether frexp works], [gl_cv_func_frexp_works],
97     [
98       AC_TRY_RUN([
99 #include <float.h>
100 #include <math.h>
101 #include <string.h>
102 int main()
103 {
104   int i;
105   volatile double x;
106 /* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
107    So we use -zero instead.  */
108   double zero = 0.0;
109   /* Test on denormalized numbers.  */
110   for (i = 1, x = 1.0; i >= DBL_MIN_EXP; i--, x *= 0.5)
111     ;
112   if (x > 0.0)
113     {
114       int exp;
115       double y = frexp (x, &exp);
116       /* On machines with IEEE754 arithmetic: x = 1.11254e-308, exp = -1022.
117          On NetBSD: y = 0.75. Correct: y = 0.5.  */
118       if (y != 0.5)
119         return 1;
120     }
121   /* Test on infinite numbers.  */
122   x = 1.0 / 0.0;
123   {
124     int exp;
125     double y = frexp (x, &exp);
126     if (y != x)
127       return 1;
128   }
129   /* Test on negative zero.  */
130   x = -zero;
131   {
132     int exp;
133     double y = frexp (x, &exp);
134     if (memcmp (&y, &x, sizeof x))
135       return 1;
136   }
137   return 0;
138 }], [gl_cv_func_frexp_works=yes], [gl_cv_func_frexp_works=no],
139       [case "$host_os" in
140          netbsd* | irix* | mingw*) gl_cv_func_frexp_works="guessing no";;
141          *)                        gl_cv_func_frexp_works="guessing yes";;
142        esac
143       ])
144     ])
145 ])