aboutsummaryrefslogtreecommitdiff
path: root/gcc/real.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/real.cc')
-rw-r--r--gcc/real.cc21
1 files changed, 16 insertions, 5 deletions
diff --git a/gcc/real.cc b/gcc/real.cc
index 95a9332..1f987d4 100644
--- a/gcc/real.cc
+++ b/gcc/real.cc
@@ -101,7 +101,7 @@ static int do_compare (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int);
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_from_integer (REAL_VALUE_TYPE *, int);
static void decimal_integer_string (char *, const REAL_VALUE_TYPE *,
size_t);
@@ -2309,7 +2309,9 @@ real_from_integer (REAL_VALUE_TYPE *r, format_helper fmt,
}
if (fmt.decimal_p ())
- decimal_from_integer (r);
+ /* We need at most one decimal digits for each 3 bits of input
+ precision. */
+ decimal_from_integer (r, val_in.get_precision () / 3);
if (fmt)
real_convert (r, fmt, r);
}
@@ -2364,12 +2366,21 @@ decimal_integer_string (char *str, const REAL_VALUE_TYPE *r_orig,
/* Convert a real with an integral value to decimal float. */
static void
-decimal_from_integer (REAL_VALUE_TYPE *r)
+decimal_from_integer (REAL_VALUE_TYPE *r, int digits)
{
char str[256];
- decimal_integer_string (str, r, sizeof (str) - 1);
- decimal_real_from_string (r, str);
+ if (digits <= 256)
+ {
+ decimal_integer_string (str, r, sizeof (str) - 1);
+ decimal_real_from_string (r, str);
+ }
+ else
+ {
+ char *s = XALLOCAVEC (char, digits);
+ decimal_integer_string (s, r, digits - 1);
+ decimal_real_from_string (r, s);
+ }
}
/* Returns 10**2**N. */