log10l: Work around inaccurate implementation on NetBSD.
[gnulib.git] / m4 / log10l.m4
blob80835f69583bd9159704bdcfa7a9474ffc769a1f
1 # log10l.m4 serial 6
2 dnl Copyright (C) 2011-2019 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.
7 AC_DEFUN([gl_FUNC_LOG10L],
9   AC_REQUIRE([gl_MATH_H_DEFAULTS])
10   AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE])
11   AC_REQUIRE([gl_FUNC_LOG10])
13   dnl Persuade glibc <math.h> to declare log10l().
14   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
16   dnl Test whether log10l() is declared. On AIX 5.1 it is not declared.
17   AC_CHECK_DECL([log10l], , [HAVE_DECL_LOG10L=0], [[#include <math.h>]])
19   dnl Test whether log10l() exists. Assume that log10l(), if it exists, is
20   dnl defined in the same library as log10().
21   save_LIBS="$LIBS"
22   LIBS="$LIBS $LOG10_LIBM"
23   AC_CHECK_FUNCS([log10l])
24   LIBS="$save_LIBS"
25   if test $ac_cv_func_log10l = yes; then
26     LOG10L_LIBM="$LOG10_LIBM"
28     save_LIBS="$LIBS"
29     LIBS="$LIBS $LOG10L_LIBM"
30     gl_FUNC_LOG10L_WORKS
31     LIBS="$save_LIBS"
32     case "$gl_cv_func_log10l_works" in
33       *yes) ;;
34       *) REPLACE_LOG10L=1 ;;
35     esac
36   else
37     HAVE_LOG10L=0
38     dnl If the function is declared but does not appear to exist, it may be
39     dnl defined as an inline function. In order to avoid a conflict, we have
40     dnl to define rpl_log10l, not log10l.
41     AC_CHECK_DECLS([log10l], [REPLACE_LOG10L=1], , [[#include <math.h>]])
42   fi
43   if test $HAVE_LOG10L = 0 || test $REPLACE_LOG10L = 1; then
44     if test $HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = 1; then
45       LOG10L_LIBM="$LOG10_LIBM"
46     else
47       if test $HAVE_LOG10L = 0; then
48         AC_REQUIRE([gl_FUNC_LOGL])
49         LOG10L_LIBM="$LOGL_LIBM"
50       fi
51     fi
52   fi
53   AC_SUBST([LOG10L_LIBM])
56 dnl Test whether log10l() works.
57 dnl On OSF/1 5.1, log10l(-0.0L) is NaN.
58 dnl On IRIX 6.5, log10l(-0.0L) is an unnormalized negative infinity
59 dnl 0xFFF00000000000007FF0000000000000, should be
60 dnl 0xFFF00000000000000000000000000000.
61 dnl On AIX 5.1, log10l(-0.0L) is finite if it's not the first log10l call
62 dnl in the program.
63 dnl On NetBSD 8.0, the result is accurate to only 16 digits.
64 AC_DEFUN([gl_FUNC_LOG10L_WORKS],
66   AC_REQUIRE([AC_PROG_CC])
67   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
68   AC_CACHE_CHECK([whether log10l works], [gl_cv_func_log10l_works],
69     [
70       AC_RUN_IFELSE(
71         [AC_LANG_SOURCE([[
72 #ifndef __NO_MATH_INLINES
73 # define __NO_MATH_INLINES 1 /* for glibc */
74 #endif
75 #include <float.h>
76 #include <math.h>
77 /* Override the values of <float.h>, like done in float.in.h.  */
78 #if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__)
79 # undef LDBL_MANT_DIG
80 # define LDBL_MANT_DIG   64
81 # undef LDBL_MIN_EXP
82 # define LDBL_MIN_EXP    (-16381)
83 # undef LDBL_MAX_EXP
84 # define LDBL_MAX_EXP    16384
85 #endif
86 #if defined __i386__ && (defined __FreeBSD__ || defined __DragonFly__)
87 # undef LDBL_MANT_DIG
88 # define LDBL_MANT_DIG   64
89 # undef LDBL_MIN_EXP
90 # define LDBL_MIN_EXP    (-16381)
91 # undef LDBL_MAX_EXP
92 # define LDBL_MAX_EXP    16384
93 #endif
94 #if (defined _ARCH_PPC || defined _POWER) && defined _AIX && (LDBL_MANT_DIG == 106) && defined __GNUC__
95 # undef LDBL_MIN_EXP
96 # define LDBL_MIN_EXP DBL_MIN_EXP
97 #endif
98 #if defined __sgi && (LDBL_MANT_DIG >= 106)
99 # undef LDBL_MANT_DIG
100 # define LDBL_MANT_DIG 106
101 # if defined __GNUC__
102 #  undef LDBL_MIN_EXP
103 #  define LDBL_MIN_EXP DBL_MIN_EXP
104 # endif
105 #endif
106 #undef log10l /* for AIX */
107 extern
108 #ifdef __cplusplus
110 #endif
111 long double log10l (long double);
112 static long double dummy (long double x) { return 0; }
113 volatile long double gx;
114 long double gy;
115 int main (int argc, char *argv[])
117   long double (* volatile my_log10l) (long double) = argc ? log10l : dummy;
118   int result = 0;
119   /* Dummy call, to trigger the AIX 5.1 bug.  */
120   gx = 0.6L;
121   gy = log10l (gx);
122   /* This test fails on AIX 5.1, IRIX 6.5, OSF/1 5.1.  */
123   {
124     gx = -0.0L;
125     gy = log10l (gx);
126     if (!(gy + gy == gy))
127       result |= 1;
128   }
129   /* This test fails on NetBSD 8.0.  */
130   {
131     const long double TWO_LDBL_MANT_DIG = /* 2^LDBL_MANT_DIG */
132       (long double) (1U << ((LDBL_MANT_DIG - 1) / 5))
133       * (long double) (1U << ((LDBL_MANT_DIG - 1 + 1) / 5))
134       * (long double) (1U << ((LDBL_MANT_DIG - 1 + 2) / 5))
135       * (long double) (1U << ((LDBL_MANT_DIG - 1 + 3) / 5))
136       * (long double) (1U << ((LDBL_MANT_DIG - 1 + 4) / 5));
137     long double x = 7.90097792256024576L;
138     long double err = (my_log10l (x) + my_log10l (1.0L / x)) * TWO_LDBL_MANT_DIG;
139     if (!(err >= -100.0L && err <= 100.0L))
140       result |= 2;
141   }
142   return result;
144 ]])],
145         [gl_cv_func_log10l_works=yes],
146         [gl_cv_func_log10l_works=no],
147         [case "$host_os" in
148                           # Guess yes on glibc systems.
149            *-gnu* | gnu*) gl_cv_func_log10l_works="guessing yes" ;;
150                           # Guess yes on native Windows.
151            mingw*)        gl_cv_func_log10l_works="guessing yes" ;;
152                           # If we don't know, assume the worst.
153            *)             gl_cv_func_log10l_works="guessing no" ;;
154          esac
155         ])
156     ])