diff options
Diffstat (limited to 'gcc/real.cc')
-rw-r--r-- | gcc/real.cc | 21 |
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. */ |