1# frexpl.m4 serial 9
2dnl Copyright (C) 2007-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_FREXPL],
8[
9  AC_REQUIRE([gl_MATH_H_DEFAULTS])
10  dnl Check whether it's declared.
11  dnl MacOS X 10.3 has frexpl() in libc but doesn't declare it in <math.h>.
12  AC_CHECK_DECL([frexpl], , [HAVE_DECL_FREXPL=0], [#include <math.h>])
13  FREXPL_LIBM=
14  if test $HAVE_DECL_FREXPL = 1; then
15    AC_CACHE_CHECK([whether frexpl() can be used without linking with libm],
16      [gl_cv_func_frexpl_no_libm],
17      [
18        AC_TRY_LINK([#include <math.h>
19                     long double x;],
20                    [int e; return frexpl (x, &e) > 0;],
21          [gl_cv_func_frexpl_no_libm=yes],
22          [gl_cv_func_frexpl_no_libm=no])
23      ])
24    if test $gl_cv_func_frexpl_no_libm = no; then
25      AC_CACHE_CHECK([whether frexpl() can be used with libm],
26        [gl_cv_func_frexpl_in_libm],
27        [
28          save_LIBS="$LIBS"
29          LIBS="$LIBS -lm"
30          AC_TRY_LINK([#include <math.h>
31                       long double x;],
32                      [int e; return frexpl (x, &e) > 0;],
33            [gl_cv_func_frexpl_in_libm=yes],
34            [gl_cv_func_frexpl_in_libm=no])
35          LIBS="$save_LIBS"
36        ])
37      if test $gl_cv_func_frexpl_in_libm = yes; then
38        FREXPL_LIBM=-lm
39      fi
40    fi
41    if test $gl_cv_func_frexpl_no_libm = yes \
42       || test $gl_cv_func_frexpl_in_libm = yes; then
43      save_LIBS="$LIBS"
44      LIBS="$LIBS $FREXPL_LIBM"
45      gl_FUNC_FREXPL_WORKS
46      LIBS="$save_LIBS"
47      case "$gl_cv_func_frexpl_works" in
48        *yes) gl_func_frexpl=yes ;;
49        *)    gl_func_frexpl=no; REPLACE_FREXPL=1; FREXPL_LIBM= ;;
50      esac
51    else
52      gl_func_frexpl=no
53    fi
54    if test $gl_func_frexpl = yes; then
55      AC_DEFINE([HAVE_FREXPL], [1],
56        [Define if the frexpl() function is available.])
57    fi
58  fi
59  if test $HAVE_DECL_FREXPL = 0 || test $gl_func_frexpl = no; then
60    AC_LIBOBJ([frexpl])
61  fi
62  AC_SUBST([FREXPL_LIBM])
63])
64
65AC_DEFUN([gl_FUNC_FREXPL_NO_LIBM],
66[
67  AC_REQUIRE([gl_MATH_H_DEFAULTS])
68  dnl Check whether it's declared.
69  dnl MacOS X 10.3 has frexpl() in libc but doesn't declare it in <math.h>.
70  AC_CHECK_DECL([frexpl], , [HAVE_DECL_FREXPL=0], [#include <math.h>])
71  if test $HAVE_DECL_FREXPL = 1; then
72    AC_CACHE_CHECK([whether frexpl() can be used without linking with libm],
73      [gl_cv_func_frexpl_no_libm],
74      [
75        AC_TRY_LINK([#include <math.h>
76                     long double x;],
77                    [int e; return frexpl (x, &e) > 0;],
78          [gl_cv_func_frexpl_no_libm=yes],
79          [gl_cv_func_frexpl_no_libm=no])
80      ])
81    if test $gl_cv_func_frexpl_no_libm = yes; then
82      gl_FUNC_FREXPL_WORKS
83      case "$gl_cv_func_frexpl_works" in
84        *yes) gl_func_frexpl_no_libm=yes ;;
85        *)    gl_func_frexpl_no_libm=no; REPLACE_FREXPL=1 ;;
86      esac
87    else
88      gl_func_frexpl_no_libm=no
89      dnl Set REPLACE_FREXPL here because the system may have frexpl in libm.
90      REPLACE_FREXPL=1
91    fi
92    if test $gl_func_frexpl_no_libm = yes; then
93      AC_DEFINE([HAVE_FREXPL_IN_LIBC], [1],
94        [Define if the frexpl() function is available in libc.])
95    fi
96  fi
97  if test $HAVE_DECL_FREXPL = 0 || test $gl_func_frexpl_no_libm = no; then
98    AC_LIBOBJ([frexpl])
99  fi
100])
101
102dnl Test whether frexpl() works on finite numbers (this fails on
103dnl MacOS X 10.4/PowerPC, on AIX 5.1, and on BeOS), on denormalized numbers
104dnl (this fails on MacOS X 10.5/i386), and also on infinite numbers (this
105dnl fails e.g. on IRIX 6.5 and mingw).
106AC_DEFUN([gl_FUNC_FREXPL_WORKS],
107[
108  AC_REQUIRE([AC_PROG_CC])
109  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
110  AC_CACHE_CHECK([whether frexpl works], [gl_cv_func_frexpl_works],
111    [
112      AC_TRY_RUN([
113#include <float.h>
114#include <math.h>
115/* Override the values of <float.h>, like done in float.in.h.  */
116#if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__)
117# undef LDBL_MIN_EXP
118# define LDBL_MIN_EXP    (-16381)
119#endif
120extern long double frexpl (long double, int *);
121int main()
122{
123  volatile long double x;
124  /* Test on finite numbers that fails on AIX 5.1.  */
125  x = 16.0L;
126  {
127    int exp = -9999;
128    frexpl (x, &exp);
129    if (exp != 5)
130      return 1;
131  }
132  /* Test on finite numbers that fails on MacOS X 10.4, because its frexpl
133     function returns an invalid (incorrectly normalized) value: it returns
134               y = { 0x3fe028f5, 0xc28f5c28, 0x3c9eb851, 0xeb851eb8 }
135     but the correct result is
136          0.505L = { 0x3fe028f5, 0xc28f5c29, 0xbc547ae1, 0x47ae1480 }  */
137  x = 1.01L;
138  {
139    int exp = -9999;
140    long double y = frexpl (x, &exp);
141    if (!(exp == 1 && y == 0.505L))
142      return 1;
143  }
144  /* Test on large finite numbers.  This fails on BeOS at i = 16322, while
145     LDBL_MAX_EXP = 16384.
146     In the loop end test, we test x against Infinity, rather than comparing
147     i with LDBL_MAX_EXP, because BeOS <float.h> has a wrong LDBL_MAX_EXP.  */
148  {
149    int i;
150    for (i = 1, x = 1.0L; x != x + x; i++, x *= 2.0L)
151      {
152        int exp = -9999;
153        frexpl (x, &exp);
154        if (exp != i)
155          return 1;
156      }
157  }
158  /* Test on denormalized numbers.  */
159  {
160    int i;
161    for (i = 1, x = 1.0L; i >= LDBL_MIN_EXP; i--, x *= 0.5L)
162      ;
163    if (x > 0.0L)
164      {
165        int exp;
166        long double y = frexpl (x, &exp);
167        /* On machines with IEEE854 arithmetic: x = 1.68105e-4932,
168           exp = -16382, y = 0.5.  On MacOS X 10.5: exp = -16384, y = 0.5.  */
169        if (exp != LDBL_MIN_EXP - 1)
170          return 1;
171      }
172  }
173  /* Test on infinite numbers.  */
174  x = 1.0L / 0.0L;
175  {
176    int exp;
177    long double y = frexpl (x, &exp);
178    if (y != x)
179      return 1;
180  }
181  return 0;
182}], [gl_cv_func_frexpl_works=yes], [gl_cv_func_frexpl_works=no],
183      [case "$host_os" in
184         aix* | beos* | darwin* | irix* | mingw* | pw*)
185            gl_cv_func_frexpl_works="guessing no";;
186         *) gl_cv_func_frexpl_works="guessing yes";;
187       esac
188      ])
189    ])
190])
191