Bug 13381 - fp-bit.c rounding problem
Summary: fp-bit.c rounding problem
Status: RESOLVED DUPLICATE of bug 12955
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 3.3.2
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-12-11 08:44 UTC by Takayuki Matsui
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Takayuki Matsui 2003-12-11 08:44:25 UTC
Multiply of 2 float numbers yield bad results, on systems which use fp-bit.c.
(eg. ARM, SH3 etc.)

0x3f800400 * 0x00000fff => 0x00001000  (0x00000fff expected)
0x3fc88888 * 0x0000000f => 0x00000018  (0x00000017 expected)
0x3f844444 * 0x0000000f => 0x00000010  (0x0000000f expected)
(hex numbers above are all 32-bits float numbers)

I think that the problem is fp-bit.c try to round twice in above calculations.
One is done in fpmul_parts(), and second rounding is done in pack_d().

I think that the fpmul_parts() and fpdiv_parts() should not do rounding,
and just help pack_d() to work correct.


--- fp-bit.c    2003-04-10 04:31:06.000000000 +0900
+++ fp-bit.c.fixed      2003-10-20 19:12:35.000000000 +0900
@@ -856,48 +856,26 @@
     }
   while (high < IMPLICIT_1)
     {
       tmp->normal_exp--;
 
       high <<= 1;
       if (low & FRACHIGH)
        high |= 1;
       low <<= 1;
     }
-  /* rounding is tricky. if we only round if it won't make us round later.  */
-#if 0
-  if (low & FRACHIGH2)
+
+  if (!ROUND_TOWARDS_ZERO)
     {
-      if (((high & GARDMASK) != GARDMSB)
-         && (((high + 1) & GARDMASK) == GARDMSB))
-       {
-         /* don't round, it gets done again later.  */
-       }
-      else
-       {
-         high++;
-       }
-    }
-#endif
-  if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
-    {
-      if (high & (1 << NGARDS))
-       {
-         /* half way, so round to even */
-         high += GARDROUND + 1;
-       }
-      else if (low)
-       {
-         /* but we really weren't half way */
-         high += GARDROUND + 1;
-       }
+      if (low) high |= 1;
     }
+
   tmp->fraction.ll = high;
   tmp->class = CLASS_NUMBER;
   return tmp;
 }
 
 FLO_type
 multiply (FLO_type arg_a, FLO_type arg_b)
 {
   fp_number_type a;
   fp_number_type b;
@@ -981,32 +959,23 @@
       {
        if (numerator >= denominator)
          {
            quotient |= bit;
            numerator -= denominator;
          }
        bit >>= 1;
        numerator *= 2;
       }
 
-    if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
+    if (!ROUND_TOWARDS_ZERO)
       {
-       if (quotient & (1 << NGARDS))
-         {
-           /* half way, so round to even */
-           quotient += GARDROUND + 1;
-         }
-       else if (numerator)
-         {
-           /* but we really weren't half way, more bits exist */
-           quotient += GARDROUND + 1;
-         }
+        if (numerator) quotient |= 1;
       }
 
     a->fraction.ll = quotient;
     return (a);
   }
 }
 
 FLO_type
 divide (FLO_type arg_a, FLO_type arg_b)
 {
--- end ---
Comment 1 Andrew Pinski 2003-12-11 18:22:25 UTC
This is a dup of bug 12955.

*** This bug has been marked as a duplicate of 12955 ***
Comment 2 Takayuki Matsui 2003-12-12 03:17:03 UTC
I'm sorry for my duplicate report.
I didn't see 12955.

I'm working for compatibility test suite of Java for 4 years,
and fp-bit.c was always a problem.
I am looking forward to next release which eliminates the need for local
work around.