This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: ping: c/41049 fixes for int to dfp conversions


On Wed, 2009-09-16 at 10:49 -0500, Richard Henderson wrote:
> On 09/15/2009 11:28 AM, Janis Johnson wrote:
> > Ping:
> >
> >    http://gcc.gnu.org/ml/gcc-patches/2009-08/msg01364.html
> 
> 
> > +  one = real_digit (1);
> > +  ten = ten_to_ptwo (0);
> > +  pten = *one;
> > +
> > +  sign = r.sign;
> > +  r.sign = 0;
> > +
> > +  dec_exp = REAL_EXP (&r) * M_LOG10_2;
> > +  for (i = 0; i < dec_exp; i++)
> > +    do_multiply (&pten, &pten, ten);
> 
> Use times_pten.  Ok with that change.
> 
> It's marginally unfortunate that you don't seem to be able
> to re-use real_to_decimal_for_mode, but I won't quibble.

Here are the changes I checked in for real.c.  Is this OK for 4.4
and 4.3 as well?

I also made a minor change to the test to use a new header file for
debugging macros.

Index: gcc/real.c
===================================================================
--- gcc/real.c	(revision 151782)
+++ gcc/real.c	(working copy)
@@ -110,6 +110,9 @@ static int do_compare (const REAL_VALUE_
 static void do_fix_trunc (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
 
 static unsigned long rtd_divmod (REAL_VALUE_TYPE *, REAL_VALUE_TYPE *);
+static void decimal_from_integer (REAL_VALUE_TYPE *);
+static void decimal_integer_string (char *, const REAL_VALUE_TYPE *,
+				    size_t);
 
 static const REAL_VALUE_TYPE * ten_to_ptwo (int);
 static const REAL_VALUE_TYPE * ten_to_mptwo (int);
@@ -2168,10 +2171,70 @@ real_from_integer (REAL_VALUE_TYPE *r, e
       normalize (r);
     }
 
-  if (mode != VOIDmode)
+  if (DECIMAL_FLOAT_MODE_P (mode))
+    decimal_from_integer (r);
+  else if (mode != VOIDmode)
     real_convert (r, mode, r);
 }
 
+/* Render R, an integral value, as a floating point constant with no
+   specified exponent.  */
+
+static void
+decimal_integer_string (char *str, const REAL_VALUE_TYPE *r_orig,
+			size_t buf_size)
+{
+  int dec_exp, digit, digits;
+  REAL_VALUE_TYPE r, pten;
+  char *p;
+  bool sign;
+
+  r = *r_orig;
+
+  if (r.cl == rvc_zero)
+    {
+      strcpy (str, "0.");
+      return;
+    }
+
+  sign = r.sign;
+  r.sign = 0;
+
+  dec_exp = REAL_EXP (&r) * M_LOG10_2;
+  digits = dec_exp + 1;
+  gcc_assert ((digits + 2) < (int)buf_size);
+
+  pten = *real_digit (1);
+  times_pten (&pten, dec_exp);
+
+  p = str;
+  if (sign)
+    *p++ = '-';
+
+  digit = rtd_divmod (&r, &pten);
+  gcc_assert (digit >= 0 && digit <= 9);
+  *p++ = digit + '0';
+  while (--digits > 0)
+    {
+      times_pten (&r, 1);
+      digit = rtd_divmod (&r, &pten);
+      *p++ = digit + '0';
+    }
+  *p++ = '.';
+  *p++ = '\0';
+}
+
+/* Convert a real with an integral value to decimal float.  */
+
+static void
+decimal_from_integer (REAL_VALUE_TYPE *r)
+{
+  char str[256];
+
+  decimal_integer_string (str, r, sizeof (str) - 1);
+  decimal_real_from_string (r, str);
+}
+
 /* Returns 10**2**N.  */
 
 static const REAL_VALUE_TYPE *



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]