Commit 547101fb by Joseph Myers Committed by Joseph Myers

re PR middle-end/21718 (real.c rounding not perfect)

	PR middle-end/21718
	* real.c: Remove comment about decimal string conversion and
	rounding errors.
	(real_from_string): Use MPFR to convert nonzero decimal constant
	to REAL_VALUE_TYPE.

testsuite:
	* gcc.dg/float-exact-1.c: New test.

From-SVN: r205119
parent 74e25e34
2013-11-20 Joseph Myers <joseph@codesourcery.com>
PR middle-end/21718
* real.c: Remove comment about decimal string conversion and
rounding errors.
(real_from_string): Use MPFR to convert nonzero decimal constant
to REAL_VALUE_TYPE.
2013-11-20 Eric Botcazou <ebotcazou@adacore.com> 2013-11-20 Eric Botcazou <ebotcazou@adacore.com>
* config/arm/arm.c (arm_dwarf_register_span): Take into account the * config/arm/arm.c (arm_dwarf_register_span): Take into account the
...@@ -57,14 +57,7 @@ ...@@ -57,14 +57,7 @@
Both of these requirements are easily satisfied. The largest target Both of these requirements are easily satisfied. The largest target
significand is 113 bits; we store at least 160. The smallest significand is 113 bits; we store at least 160. The smallest
denormal number fits in 17 exponent bits; we store 26. denormal number fits in 17 exponent bits; we store 26. */
Note that the decimal string conversion routines are sensitive to
rounding errors. Since the raw arithmetic routines do not themselves
have guard digits or rounding, the computation of 10**exp can
accumulate more than a few digits of error. The previous incarnation
of real.c successfully used a 144-bit fraction; given the current
layout of REAL_VALUE_TYPE we're forced to expand to at least 160 bits. */
/* Used to classify two numbers simultaneously. */ /* Used to classify two numbers simultaneously. */
...@@ -2029,75 +2022,50 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str) ...@@ -2029,75 +2022,50 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
else else
{ {
/* Decimal floating point. */ /* Decimal floating point. */
const REAL_VALUE_TYPE *ten = ten_to_ptwo (0); const char *cstr = str;
int d; mpfr_t m;
bool inexact;
while (*str == '0') while (*cstr == '0')
str++; cstr++;
while (ISDIGIT (*str)) if (*cstr == '.')
{ {
d = *str++ - '0'; cstr++;
do_multiply (r, r, ten); while (*cstr == '0')
if (d) cstr++;
do_add (r, r, real_digit (d), 0);
}
if (*str == '.')
{
str++;
if (r->cl == rvc_zero)
{
while (*str == '0')
str++, exp--;
}
while (ISDIGIT (*str))
{
d = *str++ - '0';
do_multiply (r, r, ten);
if (d)
do_add (r, r, real_digit (d), 0);
exp--;
}
} }
/* If the mantissa is zero, ignore the exponent. */ /* If the mantissa is zero, ignore the exponent. */
if (r->cl == rvc_zero) if (!ISDIGIT (*cstr))
goto is_a_zero; goto is_a_zero;
if (*str == 'e' || *str == 'E') /* Nonzero value, possibly overflowing or underflowing. */
mpfr_init2 (m, SIGNIFICAND_BITS);
inexact = mpfr_strtofr (m, str, NULL, 10, GMP_RNDZ);
/* The result should never be a NaN, and because the rounding is
toward zero should never be an infinity. */
gcc_assert (!mpfr_nan_p (m) && !mpfr_inf_p (m));
if (mpfr_zero_p (m) || mpfr_get_exp (m) < -MAX_EXP + 4)
{ {
bool exp_neg = false; mpfr_clear (m);
goto underflow;
str++; }
if (*str == '-') else if (mpfr_get_exp (m) > MAX_EXP - 4)
{ {
exp_neg = true; mpfr_clear (m);
str++; goto overflow;
} }
else if (*str == '+') else
str++; {
real_from_mpfr (r, m, NULL_TREE, GMP_RNDZ);
d = 0; /* 1 to 3 bits may have been shifted off (with a sticky bit)
while (ISDIGIT (*str)) because the hex digits used in real_from_mpfr did not
{ start with a digit 8 to f, but the exponent bounds above
d *= 10; should have avoided underflow or overflow. */
d += *str - '0'; gcc_assert (r->cl = rvc_normal);
if (d > MAX_EXP) /* Set a sticky bit if mpfr_strtofr was inexact. */
{ r->sig[0] |= inexact;
/* Overflowed the exponent. */
if (exp_neg)
goto underflow;
else
goto overflow;
}
str++;
}
if (exp_neg)
d = -d;
exp += d;
} }
if (exp)
times_pten (r, exp);
} }
r->sign = sign; r->sign = sign;
......
2013-11-20 Joseph Myers <joseph@codesourcery.com>
PR middle-end/21718
* gcc.dg/float-exact-1.c: New test.
2013-11-20 Richard Earnshaw <rearnsha@arm.com> 2013-11-20 Richard Earnshaw <rearnsha@arm.com>
PR rtl-optimization/54300 PR rtl-optimization/54300
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment