infnan: Configure scan for fp mantissa bytes master
authorH.Merijn Brand - Tux <h.m.brand@xs4all.nl>
Mon, 6 Jul 2015 07:22:23 +0000 (09:22 +0200)
committerH.Merijn Brand - Tux <h.m.brand@xs4all.nl>
Mon, 6 Jul 2015 07:22:23 +0000 (09:22 +0200)
backport of ed3917fd69b234bb5614cb9aed93d62238e3dcb8

U/perl/mantbits.U [new file with mode: 0644]

new file mode 100644 (file)
index 0000000..b30a255
--- /dev/null
@@ -0,0 +1,119 @@
+?RCS: $Id$
+?RCS:
+?RCS: Copyright (c) 2015 Jarkko Hietaniemi, H.Merijn Brand
+?RCS:
+?RCS: You may distribute under the terms of either the GNU General Public
+?RCS: License or the Artistic License, as specified in the README file.
+?RCS:
+?MAKE:longdblmantbits doublemantbits: Inlibc cat Compile run rm_try Setvar \
+       echo i_float i_sunmath d_longdbl longdblkind
+?MAKE:  -pick add $@ %<
+?S:doublemantbits:
+?S:    This symbol, if defined, tells how many mantissa bits
+?S:    there are in double precision floating point format.
+?S:    Note that this is usually DBL_MANT_DIG minus one, since
+?S:    with the standard IEEE 754 formats DBL_MANT_DIG includes
+?S:    the implicit bit which doesn't really exist.
+?S:.
+?S:longdblmantbits:
+?S:    This symbol, if defined, tells how many mantissa bits
+?S:    there are in long double precision floating point format.
+?S:    Note that this can be LDBL_MANT_DIG minus one,
+?S:    since LDBL_MANT_DIG can include the IEEE 754 implicit bit.
+?S:    The common x86-style 80-bit long double does not have
+?S:    an implicit bit.
+?S:.
+?C:DOUBLEMANTBITS:
+?C:    This symbol, if defined, tells how many mantissa bits
+?C:    there are in double precision floating point format.
+?C:    Note that this is usually DBL_MANT_DIG minus one, since
+?C:    with the standard IEEE 754 formats DBL_MANT_DIG includes
+?C:    the implicit bit, which doesn't really exist.
+?C:.
+?C:LONGDBLMANTBITS:
+?C:    This symbol, if defined, tells how many mantissa bits
+?C:    there are in long double precision floating point format.
+?C:    Note that this can be LDBL_MANT_DIG minus one,
+?C:    since LDBL_MANT_DIG can include the IEEE 754 implicit bit.
+?C:    The common x86-style 80-bit long double does not have
+?C:    an implicit bit.
+?C:.
+?H:#define DOUBLEMANTBITS  $doublemantbits
+?H:#define LONGDBLMANTBITS $longdblmantbits
+?H:.
+?F:!try
+: Check the length of the double mantissa
+$echo "Checking how many mantissa bits your doubles have..." >&4
+$cat >try.c <<EOP
+#$i_float I_FLOAT
+#$i_sunmath I_SUNMATH
+#ifdef I_FLOAT
+# include <float.h>
+#endif
+#ifdef I_SUNMATH
+# include <sunmath.h>
+#endif
+#ifdef DBL_MANT_DIG
+# define BITS (DBL_MANT_DIG - 1) /* the implicit bit does not count */
+#endif
+#include <stdio.h>
+int main(int argc, char *argv[]) {
+#ifdef BITS
+  printf("%d\n", BITS);
+#endif
+  return 0;
+}
+EOP
+set try
+if eval $compile; then
+    doublemantbits=`$run ./try`
+else
+    doublemantbits="$undef"
+fi
+$rm_try
+
+: Check the length of the longdouble mantissa
+$echo "Checking how many mantissa bits your long doubles have..." >&4
+$cat >try.c <<EOP
+#$i_float I_FLOAT
+#$i_sunmath I_SUNMATH
+#ifdef I_FLOAT
+# include <float.h>
+#endif
+#ifdef I_SUNMATH
+# include <sunmath.h>
+#endif
+#$d_longdbl HAS_LONG_DOUBLE
+#if defined(HAS_LONG_DOUBLE) && defined(LDBL_MANT_DIG)
+# if ($longdblkind == 3) || ($longdblkind == 4) /* 80-bit extended precision */
+/* This format has no implicit bit.  Beware, however, that for
+ * this format the bare LDBL_MANT_DIG is misleading for inf/nan:
+ * the top three bits are used for inf (100) / qnan (11x) / snan (101),
+ * and the top bit must have been one since 387, zero is plain invalid.
+ * For normal fp values, the LDBL_MANT_DIG is fine, though. */
+#  define BITS LDBL_MANT_DIG
+# elif ($longdblkind == 5 || $longdblkind == 6) /* double double */
+/* LDBL_MANT_DIG of 106 (twice 53) would be logical, but for some
+ * reason e.g. Irix thinks 107.  But in any case, we want only
+ * the number of real bits, the implicit bits are of no interest.  */
+#  define BITS 2 * (DBL_MANT_DIG - 1)
+# else
+#  define BITS (LDBL_MANT_DIG - 1) /* the implicit bit does not count */
+# endif
+#endif
+#include <stdio.h>
+int main(int argc, char *argv[]) {
+#ifdef BITS
+  printf("%d\n", BITS);
+#endif
+  return 0;
+}
+EOP
+set try
+if eval $compile; then
+    longdblmantbits=`$run ./try`
+else
+    longdblmantbits="$undef"
+fi
+$rm_try
+