This is the mail archive of the gcc@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: real_from_string fails to convert negative values


On Sun, Sep 29, 2002 at 10:45:44AM -0700, Richard Henderson wrote:
> On Sat, Sep 28, 2002 at 10:37:21PM +0100, Paul Brook wrote:
> > The real_from_string function in real.c doesn't seem to convert negative 
> > numbers correctly. It seems to return the absolute (ie. positive) value of 
> > the value, and ignore any preceeding - signs.
> 
> Sure enough.  The existing code only works for -0.  I'll have it fixed
> in a moment.

Like so.


r~


        * real.c (real_from_string): Apply sign last.  Tidy exponent handling.

Index: real.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/real.c,v
retrieving revision 1.94
diff -c -p -d -u -r1.94 real.c
--- real.c	29 Sep 2002 21:23:45 -0000	1.94
+++ real.c	30 Sep 2002 05:59:36 -0000
@@ -1579,12 +1579,13 @@ real_from_string (r, str)
      const char *str;
 {
   int exp = 0;
+  bool sign = false;
 
   get_zero (r, 0);
 
   if (*str == '-')
     {
-      r->sign = 1;
+      sign = true;
       str++;
     }
   else if (*str == '+')
@@ -1616,6 +1617,11 @@ real_from_string (r, str)
       if (*str == '.')
 	{
 	  str++;
+	  if (pos == SIGNIFICAND_BITS - 4)
+	    {
+	      while (*str == '0')
+		str++, exp -= 4;
+	    }
 	  while (1)
 	    {
 	      d = hex_value (*str);
@@ -1632,12 +1638,12 @@ real_from_string (r, str)
 	}
       if (*str == 'p' || *str == 'P')
 	{
-	  int exp_neg = 0;
+	  bool exp_neg = false;
 
 	  str++;
 	  if (*str == '-')
 	    {
-	      exp_neg = 1;
+	      exp_neg = true;
 	      str++;
 	    }
 	  else if (*str == '+')
@@ -1646,10 +1652,9 @@ real_from_string (r, str)
 	  d = 0;
 	  while (ISDIGIT (*str))
 	    {
-	      int t = d;
 	      d *= 10;
 	      d += *str - '0';
-	      if (d < t)
+	      if (d > MAX_EXP)
 		{
 		  /* Overflowed the exponent.  */
 		  if (exp_neg)
@@ -1667,13 +1672,6 @@ real_from_string (r, str)
 
       r->class = rvc_normal;
       r->exp = exp;
-      if (r->exp != exp)
-	{
-	  if (exp < 0)
-	    goto underflow;
-	  else
-	    goto overflow;
-	}
 
       normalize (r);
     }
@@ -1695,6 +1693,11 @@ real_from_string (r, str)
       if (*str == '.')
 	{
 	  str++;
+	  if (r->class == rvc_zero)
+	    {
+	      while (*str == '0')
+		str++, exp--;
+	    }
 	  while (ISDIGIT (*str))
 	    {
 	      d = *str++ - '0';
@@ -1707,12 +1710,12 @@ real_from_string (r, str)
 
       if (*str == 'e' || *str == 'E')
 	{
-	  int exp_neg = 0;
+	  bool exp_neg = false;
 
 	  str++;
 	  if (*str == '-')
 	    {
-	      exp_neg = 1;
+	      exp_neg = true;
 	      str++;
 	    }
 	  else if (*str == '+')
@@ -1721,10 +1724,9 @@ real_from_string (r, str)
 	  d = 0;
 	  while (ISDIGIT (*str))
 	    {
-	      int t = d;
 	      d *= 10;
 	      d += *str - '0';
-	      if (d < t)
+	      if (d > MAX_EXP)
 		{
 		  /* Overflowed the exponent.  */
 		  if (exp_neg)
@@ -1754,14 +1756,15 @@ real_from_string (r, str)
 	}
     }
 
+  r->sign = sign;
   return;
 
  underflow:
-  get_zero (r, r->sign);
+  get_zero (r, sign);
   return;
 
  overflow:
-  get_inf (r, r->sign);
+  get_inf (r, sign);
   return;
 }
 


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