]> Savannah Git Hosting - gnulib.git/commitdiff
expl: avoid incorrect expl(small_value) on OpenBSD 5.4
authorAssaf Gordon <agordon@wi.mit.edu>
Wed, 16 Apr 2014 15:35:55 +0000 (11:35 -0400)
committerPádraig Brady <P@draigBrady.com>
Wed, 16 Apr 2014 22:12:55 +0000 (23:12 +0100)
OpenBSD 5.4, expl() incorrectly returns 'nan' for small values.
Detect this and use gnulib's expl() in that case.

Discussed here:
http://marc.info/?t=139159081700002&r=1&w=2
(Message from David Coppa on 2014-02-05 to openbsd-tech mailing list).

Fixed here (in revision 1.2):
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libm/src/ld128/s_floorl.c

* m4/expl.m4 (gl_FUNC_EXPL): Add a check for this condition.
* doc/posix-functions/expl.texi: Mention the workaround.

ChangeLog
doc/posix-functions/expl.texi
m4/expl.m4

index 6bf7c0085d07a914035a92bd00a738d25b7e44bc..a298177cd2eaf6557d24e8ea9b929c4499c99b23 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-04-16  Assaf Gordon  <agordon@wi.mit.edu>
+
+       expl: avoid incorrect expl(small_value) on OpenBSD 5.4
+       * m4/expl.m4 (gl_FUNC_EXPL): Add a check for this condition.
+       * doc/posix-functions/expl.texi: Mention the workaround.
+
 2014-04-12  Paul Eggert  <eggert@cs.ucla.edu>
 
        xalloc: allow x2nrealloc (P, PN, S) where P && !*PN
index f198d003567eadc241967f5a0e3a2b4acecc6973..633e684081d5fac8174a559bf49f423f8a3b106b 100644 (file)
@@ -12,6 +12,9 @@ Portability problems fixed by Gnulib:
 This function is missing on some platforms:
 FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, HP-UX 11, IRIX 6.5, Solaris 9, Cygwin, Interix 3.5, BeOS.
 @item
+This function returns NaN for small operands:
+OpenBSD 5.4.
+@item
 This function is only defined as a macro with arguments on some platforms:
 MSVC 9.
 @item
index 247bc6e8b9ecb517e8ee13354c565e94bedb57af..fca810b3ed4ef5947e40ea6e09df7edc7e61c586 100644 (file)
@@ -53,6 +53,34 @@ AC_DEFUN([gl_FUNC_EXPL],
       EXPL_LIBM=-lm
     fi
   fi
+  dnl On OpenBSD5.4 the system's native expl() is buggy:
+  dnl it returns 'nan' for small values. Test for this anomaly.
+  if test $gl_cv_func_expl_no_libm = yes \
+     || test $gl_cv_func_expl_in_libm = yes; then
+    AC_CACHE_CHECK([whether expl() breaks with small values],
+        [gl_cv_func_expl_buggy],
+        [
+          save_LIBS="$LIBS"
+          LIBS="$EXPL_LIBM"
+          AC_RUN_IFELSE(
+           [AC_LANG_PROGRAM(
+             [[#include <math.h>]],
+             [[return isnan(expl(-1.0))||
+                      isnan(expl(-0.8))||
+                      isnan(expl(-0.4)); ]])],
+             [gl_cv_func_expl_buggy=no], [gl_cv_func_expl_buggy=yes],
+             [case $host_os in
+                openbsd*) gl_cv_func_expl_buggy="guessing yes";;
+                *) gl_cv_func_expl_buggy="guessing no";;
+              esac])
+          LIBS="$save_LIBS"
+        ])
+    case "$gl_cv_func_expl_buggy" in
+      *yes)
+        gl_cv_func_expl_in_libm=no
+        gl_cv_func_expl_no_libm=no ;;
+    esac
+  fi
   if test $gl_cv_func_expl_no_libm = yes \
      || test $gl_cv_func_expl_in_libm = yes; then
     dnl Also check whether it's declared.