[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
isinf on OpenBSD
From: |
Bruno Haible |
Subject: |
isinf on OpenBSD |
Date: |
Sat, 1 Oct 2011 12:07:52 +0200 |
User-agent: |
KMail/1.13.6 (Linux/2.6.37.6-0.5-desktop; KDE/4.6.0; x86_64; ; ) |
On OpenBSD 4.9/x86 I get this test failure:
test-isinf.c:214: assertion failed
FAIL: test-isinf
Apparently isinf considers pseudo-infinities to be infinities. This patch
fixes it.
2011-10-01 Bruno Haible <address@hidden>
isinf: Fix for OpenBSD/x86.
* m4/isinf.m4 (gl_ISINFL_WORKS): Also test the behaviour of isinf on
pseudo-NaNs, pseudo-Infinities, and other non-IEEE values.
* doc/posix-functions/isinf.texi: Mention the problem on OpenBSD/x86.
--- doc/posix-functions/isinf.texi.orig Sat Oct 1 12:04:22 2011
+++ doc/posix-functions/isinf.texi Sat Oct 1 12:02:18 2011
@@ -11,6 +11,10 @@
@item
This macro is missing on some platforms:
AIX 4.3.2, IRIX 6.5, OSF/1 5.1, Solaris 11 2010-11.
address@hidden
+This macro incorrectly yields true for some @samp{long double} arguments, on
+some platforms:
+OpenBSD 4.9/x86 (pseudo-Infinity).
@end itemize
Portability problems not fixed by Gnulib:
--- m4/isinf.m4.orig Sat Oct 1 12:04:22 2011
+++ m4/isinf.m4 Sat Oct 1 11:55:14 2011
@@ -1,4 +1,4 @@
-# isinf.m4 serial 6
+# isinf.m4 serial 7
dnl Copyright (C) 2007-2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -30,7 +30,15 @@
AC_SUBST([ISINF_LIBM])
])
-dnl Test whether isinf() correctly returns false for LDBL_MAX.
+dnl Test whether isinf() works:
+dnl 1) Whether it correctly returns false for LDBL_MAX.
+dnl 2) Whether on 'long double' recognizes all numbers which are neither
+dnl finite nor infinite. This test fails on OpenBSD/x86, but could also
+dnl fail e.g. on i686, x86_64, ia64, because of
+dnl - pseudo-denormals on x86_64,
+dnl - pseudo-zeroes, unnormalized numbers, and pseudo-denormals on i686,
+dnl - pseudo-NaN, pseudo-Infinity, pseudo-zeroes, unnormalized numbers, and
+dnl pseudo-denormals on ia64.
AC_DEFUN([gl_ISINFL_WORKS],
[
AC_REQUIRE([AC_PROG_CC])
@@ -38,11 +46,124 @@
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
AC_CACHE_CHECK([whether isinf(long double) works], [gl_cv_func_isinfl_works],
[
- AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <float.h>
- #include <math.h>]],
- [[return !!isinf(LDBL_MAX);]])],
- [gl_cv_func_isinfl_works=yes],
- [gl_cv_func_isinfl_works=no],
- [gl_cv_func_isinfl_works="guessing no"])
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#define NWORDS \
+ ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+typedef union { unsigned int word[NWORDS]; long double value; }
+ memory_long_double;
+/* On Irix 6.5, gcc 3.4.3 can't compute compile-time NaN, and needs the
+ runtime type conversion. */
+#ifdef __sgi
+static long double NaNl ()
+{
+ double zero = 0.0;
+ return zero / zero;
+}
+#else
+# define NaNl() (0.0L / 0.0L)
+#endif
+int main ()
+{
+ int result = 0;
+
+ if (isinf (LDBL_MAX))
+ result |= 1;
+
+ {
+ memory_long_double m;
+ unsigned int i;
+
+ /* The isinf macro should be immune against changes in the sign bit and
+ in the mantissa bits. The xor operation twiddles a bit that can only be
+ a sign bit or a mantissa bit (since the exponent never extends to
+ bit 31). */
+ m.value = NaNl ();
+ m.word[NWORDS / 2] ^= (unsigned int) 1 << (sizeof (unsigned int) *
CHAR_BIT - 1);
+ for (i = 0; i < NWORDS; i++)
+ m.word[i] |= 1;
+ if (isinf (m.value))
+ result |= 2;
+ }
+
+#if ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined
__amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined
_M_IX86 || defined _X86_))
+/* Representation of an 80-bit 'long double' as an initializer for a sequence
+ of 'unsigned int' words. */
+# ifdef WORDS_BIGENDIAN
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+ { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
+ ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \
+ (unsigned int) (mantlo) << 16 \
+ }
+# else
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+ { mantlo, manthi, exponent }
+# endif
+ { /* Quiet NaN. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ if (isinf (x.value))
+ result |= 2;
+ }
+ {
+ /* Signalling NaN. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ if (isinf (x.value))
+ result |= 2;
+ }
+ /* The isinf macro should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ if (isinf (x.value))
+ result |= 4;
+ }
+ { /* Pseudo-Infinity. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ if (isinf (x.value))
+ result |= 8;
+ }
+ { /* Pseudo-Zero. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ if (isinf (x.value))
+ result |= 16;
+ }
+ { /* Unnormalized number. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ if (isinf (x.value))
+ result |= 32;
+ }
+ { /* Pseudo-Denormal. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ if (isinf (x.value))
+ result |= 64;
+ }
+#endif
+
+ return result;
+}]])], [gl_cv_func_isinfl_works=yes], [gl_cv_func_isinfl_works=no],
+ [
+ case "$host" in
+ # Guess no on OpenBSD ia64, x86_64, i386.
+ ia64-*-openbsd* | x86_64-*-openbsd* | i*86-*-openbsd*)
+ gl_cv_func_isinfl_works="guessing no";;
+ *)
+ gl_cv_func_isinfl_works="guessing yes";;
+ esac
+ ])
])
])
--
In memoriam Max Ehrlich <http://en.wikipedia.org/wiki/Max_Ehrlich>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- isinf on OpenBSD,
Bruno Haible <=