trans-const.c (gfc_conv_mpfr_to_tree): Use hexadecimal string as intermediate represe...
authorTobias Schlüter <tobias.schlueter@physik.uni-muenchen.de>
Sat, 23 Apr 2005 15:19:06 +0000 (17:19 +0200)
committerTobias Schlüter <tobi@gcc.gnu.org>
Sat, 23 Apr 2005 15:19:06 +0000 (17:19 +0200)
* trans-const.c (gfc_conv_mpfr_to_tree): Use hexadecimal string as
intermediate representation.

From-SVN: r98619

gcc/fortran/ChangeLog
gcc/fortran/trans-const.c

index 46247ceff826b9cd8e6981ebdcadeeea3f0dbf6e..a20c922277809e8546f4c171382ce87878113f17 100644 (file)
@@ -1,3 +1,8 @@
+2005-04-23  Tobias Schl"uter  <tobias.schlueter@physik.uni-muenchen.de>
+
+       * trans-const.c (gfc_conv_mpfr_to_tree): Use hexadecimal string as
+       intermediate representation.
+
 2005-04-21  Steven G. Kargl  <kargls@comcast.net>
 
        * trans-const.c (gfc_conv_mpfr_to_tree): Remove unneeded computation;
index a6387199bd7d9314048dab83ae87ac835b9a6891..59009c1e32fc744aa601d8f535602cefdc637eba 100644 (file)
@@ -224,27 +224,29 @@ gfc_conv_mpfr_to_tree (mpfr_t f, int kind)
   char *p, *q;
   int n;
 
-  for (n = 0; gfc_real_kinds[n].kind != 0; n++)
-    {
-      if (gfc_real_kinds[n].kind == kind)
-       break;
-    }
-  gcc_assert (gfc_real_kinds[n].kind);
+  n = gfc_validate_kind (BT_REAL, kind, false);
 
-  /* A decimal representation is used here, which requires the additional
-     two characters for rounding.  TODO: Use a hexadecimal representation
-     to avoid rounding issues.  */
-  p = mpfr_get_str (NULL, &exp, 10, gfc_real_kinds[n].precision+2,
+  gcc_assert (gfc_real_kinds[n].radix == 2);
+
+  /* mpfr chooses too small a number of hexadecimal digits if the
+     number of binary digits is not divisible by four, therefore we
+     have to explicitly request a sufficient number of digits here.  */
+  p = mpfr_get_str (NULL, &exp, 16, gfc_real_kinds[n].digits / 4 + 1,
                    f, GFC_RND_MODE);
-  gcc_assert (p);
 
-  /* The additional 10 characters add space for the sprintf below.  */
-  q = (char *) gfc_getmem (strlen (p) + 10);
+  /* REAL_VALUE_ATOF expects the exponent for mantissae * 2**exp,
+     mpfr_get_str returns the exponent for mantissa * 16**exp, adjust
+     for that.  */
+  exp *= 4;
+
+  /* The additional 12 characters add space for the sprintf below.
+     This leaves 6 digits for the exponent which is certainly enough.  */
+  q = (char *) gfc_getmem (strlen (p) + 12);
 
   if (p[0] == '-')
-    sprintf (q, "-.%se%d", &p[1], (int) exp);
+    sprintf (q, "-0x.%sp%d", &p[1], (int) exp);
   else
-    sprintf (q, ".%se%d", p, (int) exp);
+    sprintf (q, "0x.%sp%d", p, (int) exp);
 
   type = gfc_get_real_type (kind);
   res = build_real (type, REAL_VALUE_ATOF (q, TYPE_MODE (type)));