re PR middle-end/21720 (GCC incorrectly rounds hex floats)
authorJoseph Myers <joseph@codesourcery.com>
Fri, 29 Jul 2005 21:14:22 +0000 (22:14 +0100)
committerJoseph Myers <jsm28@gcc.gnu.org>
Fri, 29 Jul 2005 21:14:22 +0000 (22:14 +0100)
PR c/21720
* real.c (real_from_string): Also set last bit if there is a
nonzero hex digit beyond GCC's internal precision after ".".

testsuite:
* gcc.dg/hex-round-1.c: Test more cases.
* gcc.dg/hex-round-2.c: New test.

From-SVN: r102567

gcc/ChangeLog
gcc/real.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/hex-round-1.c
gcc/testsuite/gcc.dg/hex-round-2.c [new file with mode: 0644]

index 980c491..781ab8b 100644 (file)
@@ -1,3 +1,9 @@
+2005-07-29  Joseph S. Myers  <joseph@codesourcery.com>
+
+       PR c/21720
+       * real.c (real_from_string): Also set last bit if there is a
+       nonzero hex digit beyond GCC's internal precision after ".".
+
 2005-07-29  David Edelsohn  <edelsohn@gnu.org>
 
        * config/rs6000/altivec.md: Convert UNSPEC numerical values to
index 045a803..2d26185 100644 (file)
@@ -1815,6 +1815,10 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
                    |= (unsigned long) d << (pos % HOST_BITS_PER_LONG);
                  pos -= 4;
                }
+             else if (d)
+               /* Ensure correct rounding by setting last bit if there is
+                  a subsequent nonzero digit.  */
+               r->sig[0] |= 1;
              str++;
            }
        }
index aa60bc1..9516f68 100644 (file)
@@ -1,3 +1,9 @@
+2005-07-29  Joseph S. Myers  <joseph@codesourcery.com>
+
+       PR c/21720
+       * gcc.dg/hex-round-1.c: Test more cases.
+       * gcc.dg/hex-round-2.c: New test.
+
 2005-07-29  Diego Novillo  <dnovillo@redhat.com>
 
        PR 22550
index 1ce9c35..3276ad4 100644 (file)
@@ -10,6 +10,64 @@ int
 main (void)
 {
 #if FLT_RADIX == 2 && FLT_MANT_DIG == 24
+  if (0x1.0000011p0f == 1)
+    link_failure ();
+  if (0x1.00000101p0f == 1)
+    link_failure ();
+  if (0x1.000001001p0f == 1)
+    link_failure ();
+  if (0x1.0000010001p0f == 1)
+    link_failure ();
+  if (0x1.00000100001p0f == 1)
+    link_failure ();
+  if (0x1.000001000001p0f == 1)
+    link_failure ();
+  if (0x1.0000010000001p0f == 1)
+    link_failure ();
+  if (0x1.00000100000001p0f == 1)
+    link_failure ();
+  if (0x1.000001000000001p0f == 1)
+    link_failure ();
+  if (0x1.0000010000000001p0f == 1)
+    link_failure ();
+  if (0x1.00000100000000001p0f == 1)
+    link_failure ();
+  if (0x1.000001000000000001p0f == 1)
+    link_failure ();
+  if (0x1.0000010000000000001p0f == 1)
+    link_failure ();
+  if (0x1.00000100000000000001p0f == 1)
+    link_failure ();
+  if (0x1.000001000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.0000010000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.00000100000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.000001000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.0000010000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.00000100000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.000001000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.0000010000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.00000100000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.000001000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.0000010000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.00000100000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.000001000000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.0000010000000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.00000100000000000000000000000000001p0f == 1)
+    link_failure ();
   if (0x1.000001000000000000000000000000000001p0f == 1)
     link_failure ();
   if (0x1.0000010000000000000000000000000000001p0f == 1)
@@ -26,6 +84,30 @@ main (void)
     link_failure ();
   if (0x1.0000010000000000000000000000000000000000001p0f == 1)
     link_failure ();
+  if (0x1.00000100000000000000000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.000001000000000000000000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.0000010000000000000000000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.00000100000000000000000000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.000001000000000000000000000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.0000010000000000000000000000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.00000100000000000000000000000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.000001000000000000000000000000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.0000010000000000000000000000000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.00000100000000000000000000000000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.000001000000000000000000000000000000000000000000000001p0f == 1)
+    link_failure ();
+  if (0x1.0000010000000000000000000000000000000000000000000000001p0f == 1)
+    link_failure ();
 #endif
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/hex-round-2.c b/gcc/testsuite/gcc.dg/hex-round-2.c
new file mode 100644 (file)
index 0000000..ba9b8bf
--- /dev/null
@@ -0,0 +1,114 @@
+/* Test for hexadecimal float rounding: bug 21720.  Test with no "."
+   in number.  */
+/* { dg-do link } */
+/* { dg-options "-O -std=gnu99" } */
+
+#include <float.h>
+
+extern void link_failure (void);
+
+int
+main (void)
+{
+#if FLT_RADIX == 2 && FLT_MANT_DIG == 24
+  if (0x10000011p-28f == 1)
+    link_failure ();
+  if (0x100000101p-32f == 1)
+    link_failure ();
+  if (0x1000001001p-36f == 1)
+    link_failure ();
+  if (0x10000010001p-40f == 1)
+    link_failure ();
+  if (0x100000100001p-44f == 1)
+    link_failure ();
+  if (0x1000001000001p-48f == 1)
+    link_failure ();
+  if (0x10000010000001p-52f == 1)
+    link_failure ();
+  if (0x100000100000001p-56f == 1)
+    link_failure ();
+  if (0x1000001000000001p-60f == 1)
+    link_failure ();
+  if (0x10000010000000001p-64f == 1)
+    link_failure ();
+  if (0x100000100000000001p-68f == 1)
+    link_failure ();
+  if (0x1000001000000000001p-72f == 1)
+    link_failure ();
+  if (0x10000010000000000001p-76f == 1)
+    link_failure ();
+  if (0x100000100000000000001p-80f == 1)
+    link_failure ();
+  if (0x1000001000000000000001p-84f == 1)
+    link_failure ();
+  if (0x10000010000000000000001p-88f == 1)
+    link_failure ();
+  if (0x100000100000000000000001p-92f == 1)
+    link_failure ();
+  if (0x1000001000000000000000001p-96f == 1)
+    link_failure ();
+  if (0x10000010000000000000000001p-100f == 1)
+    link_failure ();
+  if (0x100000100000000000000000001p-104f == 1)
+    link_failure ();
+  if (0x1000001000000000000000000001p-108f == 1)
+    link_failure ();
+  if (0x10000010000000000000000000001p-112f == 1)
+    link_failure ();
+  if (0x100000100000000000000000000001p-116f == 1)
+    link_failure ();
+  if (0x1000001000000000000000000000001p-120f == 1)
+    link_failure ();
+  if (0x10000010000000000000000000000001p-124f == 1)
+    link_failure ();
+  if (0x100000100000000000000000000000001p-128f == 1)
+    link_failure ();
+  if (0x1000001000000000000000000000000001p-132f == 1)
+    link_failure ();
+  if (0x10000010000000000000000000000000001p-136f == 1)
+    link_failure ();
+  if (0x100000100000000000000000000000000001p-140f == 1)
+    link_failure ();
+  if (0x1000001000000000000000000000000000001p-144f == 1)
+    link_failure ();
+  if (0x10000010000000000000000000000000000001p-148f == 1)
+    link_failure ();
+  if (0x100000100000000000000000000000000000001p-152f == 1)
+    link_failure ();
+  if (0x1000001000000000000000000000000000000001p-156f == 1)
+    link_failure ();
+  if (0x10000010000000000000000000000000000000001p-160f == 1)
+    link_failure ();
+  if (0x100000100000000000000000000000000000000001p-164f == 1)
+    link_failure ();
+  if (0x1000001000000000000000000000000000000000001p-168f == 1)
+    link_failure ();
+  if (0x10000010000000000000000000000000000000000001p-172f == 1)
+    link_failure ();
+  if (0x100000100000000000000000000000000000000000001p-176f == 1)
+    link_failure ();
+  if (0x1000001000000000000000000000000000000000000001p-180f == 1)
+    link_failure ();
+  if (0x10000010000000000000000000000000000000000000001p-184f == 1)
+    link_failure ();
+  if (0x100000100000000000000000000000000000000000000001p-188f == 1)
+    link_failure ();
+  if (0x1000001000000000000000000000000000000000000000001p-192f == 1)
+    link_failure ();
+  if (0x10000010000000000000000000000000000000000000000001p-196f == 1)
+    link_failure ();
+  if (0x100000100000000000000000000000000000000000000000001p-200f == 1)
+    link_failure ();
+  if (0x1000001000000000000000000000000000000000000000000001p-204f == 1)
+    link_failure ();
+  if (0x10000010000000000000000000000000000000000000000000001p-208f == 1)
+    link_failure ();
+  if (0x100000100000000000000000000000000000000000000000000001p-212f == 1)
+    link_failure ();
+  if (0x1000001000000000000000000000000000000000000000000000001p-216f == 1)
+    link_failure ();
+  if (0x10000010000000000000000000000000000000000000000000000001p-220f == 1)
+    link_failure ();
+#endif
+  return 0;
+}