frexp, tests: work around ICC bug with -zero
[gnulib.git] / m4 / frexp.m4
1 # frexp.m4 serial 9
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_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   else
48     AC_LIBOBJ([frexp])
49   fi
50   AC_SUBST([FREXP_LIBM])
51 ])
52
53 AC_DEFUN([gl_FUNC_FREXP_NO_LIBM],
54 [
55   AC_REQUIRE([gl_MATH_H_DEFAULTS])
56   AC_REQUIRE([gl_CHECK_FREXP_NO_LIBM])
57   if test $gl_cv_func_frexp_no_libm = yes; then
58     gl_FUNC_FREXP_WORKS
59     case "$gl_cv_func_frexp_works" in
60       *yes) gl_func_frexp_no_libm=yes ;;
61       *)    gl_func_frexp_no_libm=no; REPLACE_FREXP=1 ;;
62     esac
63   else
64     gl_func_frexp_no_libm=no
65     dnl Set REPLACE_FREXP here because the system may have frexp in libm.
66     REPLACE_FREXP=1
67   fi
68   if test $gl_func_frexp_no_libm = yes; then
69     AC_DEFINE([HAVE_FREXP_IN_LIBC], [1],
70       [Define if the frexp() function is available in libc.])
71   else
72     AC_LIBOBJ([frexp])
73   fi
74 ])
75
76 dnl Test whether frexp() can be used without linking with libm.
77 dnl Set gl_cv_func_frexp_no_libm to 'yes' or 'no' accordingly.
78 AC_DEFUN([gl_CHECK_FREXP_NO_LIBM],
79 [
80   AC_CACHE_CHECK([whether frexp() can be used without linking with libm],
81     [gl_cv_func_frexp_no_libm],
82     [
83       AC_LINK_IFELSE(
84         [AC_LANG_PROGRAM(
85            [[#include <math.h>
86              double x;]],
87            [[int e; return frexp (x, &e) > 0;]])],
88         [gl_cv_func_frexp_no_libm=yes],
89         [gl_cv_func_frexp_no_libm=no])
90     ])
91 ])
92
93 dnl Test whether frexp() works also on denormalized numbers (this fails e.g. on
94 dnl NetBSD 3.0), on infinite numbers (this fails e.g. on IRIX 6.5 and mingw),
95 dnl and on negative zero (this fails e.g. on NetBSD 4.99).
96 AC_DEFUN([gl_FUNC_FREXP_WORKS],
97 [
98   AC_REQUIRE([AC_PROG_CC])
99   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
100   AC_CACHE_CHECK([whether frexp works], [gl_cv_func_frexp_works],
101     [
102       AC_RUN_IFELSE(
103         [AC_LANG_SOURCE([[
104 #include <float.h>
105 #include <math.h>
106 #include <string.h>
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 MacOS X 10.5.  */
111 #if defined __hpux || defined __sgi || defined __ICC
112 static double
113 compute_minus_zero (void)
114 {
115   return -DBL_MIN * DBL_MIN;
116 }
117 # define minus_zero compute_minus_zero ()
118 #else
119 double minus_zero = -0.0;
120 #endif
121 int main()
122 {
123   int i;
124   volatile double x;
125   double zero = 0.0;
126   /* Test on denormalized numbers.  */
127   for (i = 1, x = 1.0; i >= DBL_MIN_EXP; i--, x *= 0.5)
128     ;
129   if (x > 0.0)
130     {
131       int exp;
132       double y = frexp (x, &exp);
133       /* On machines with IEEE754 arithmetic: x = 1.11254e-308, exp = -1022.
134          On NetBSD: y = 0.75. Correct: y = 0.5.  */
135       if (y != 0.5)
136         return 1;
137     }
138   /* Test on infinite numbers.  */
139   x = 1.0 / 0.0;
140   {
141     int exp;
142     double y = frexp (x, &exp);
143     if (y != x)
144       return 1;
145   }
146   /* Test on negative zero.  */
147   x = minus_zero;
148   {
149     int exp;
150     double y = frexp (x, &exp);
151     if (memcmp (&y, &x, sizeof x))
152       return 1;
153   }
154   return 0;
155 }]])],
156         [gl_cv_func_frexp_works=yes],
157         [gl_cv_func_frexp_works=no],
158         [case "$host_os" in
159            netbsd* | irix* | mingw*) gl_cv_func_frexp_works="guessing no";;
160            *)                        gl_cv_func_frexp_works="guessing yes";;
161          esac
162         ])
163     ])
164 ])