On Thu, Apr 07, 2005 at 07:14:05PM +0100, Paul Brook wrote:
> On Thursday 07 April 2005 18:54, Steve Kargl wrote:
> > On Thu, Apr 07, 2005 at 01:41:21PM -0400, Geert Bosch wrote:
> > > On Apr 7, 2005, at 13:27, Steve Kargl wrote:
> > > >Try -fdump-parse-tree. You've given more digits in y than
> > > >its precision. This is permitted by the standard. It appears
> > > >the gfortran frontend is taking y = 0.499999 and the closest
> > > >representable nubmer is y = 0.5.
> > >
> > > So, why does the test y < 0.5 yield true then?
> >
> > I missed that part of the output. The exceeding
> > long string of digits caught my attention. Can
> > you submit a PR? The problem, I believe, is in
> > gfc_simplify_nint
>
> Unlikely, although that may also be buggy. fc_simplify_* only applies to
> compile time costants. You probably want build_round_expr in
> trans-intrinsic.c
>
It's buggy. If I have time this weekend, I'll check build_round_expr.
Meanwhile, the attached patch and testcase fix the problem with gfortran's
constant folding. Bubblestrapped and Regression tested on mainline
for amd64-*-freebsd.
Ok to commit to mainline? Ok to commit to 4.0 after strapping
and testing?
2005-04-08 Steven G. Kargl <[EMAIL PROTECTED]>
* simplify.c (simplify_nint): Fix rounding for corner cases
2005-04-08 Steven G. Kargl <[EMAIL PROTECTED]>
* gfortran.dg/nint_1.f90: New test.
--
Steve
Index: simplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/simplify.c,v
retrieving revision 1.21
diff -c -p -r1.21 simplify.c
*** simplify.c 7 Apr 2005 18:26:37 -0000 1.21
--- simplify.c 8 Apr 2005 17:52:43 -0000
*************** gfc_simplify_nearest (gfc_expr * x, gfc_
*** 2378,2386 ****
static gfc_expr *
simplify_nint (const char *name, gfc_expr * e, gfc_expr * k)
{
! gfc_expr *rtrunc, *itrunc, *result;
! int kind, cmp;
! mpfr_t half;
kind = get_kind (BT_INTEGER, k, name, gfc_default_integer_kind);
if (kind == -1)
--- 2378,2385 ----
static gfc_expr *
simplify_nint (const char *name, gfc_expr * e, gfc_expr * k)
{
! gfc_expr *itrunc, *result;
! int kind;
kind = get_kind (BT_INTEGER, k, name, gfc_default_integer_kind);
if (kind == -1)
*************** simplify_nint (const char *name, gfc_exp
*** 2391,2423 ****
result = gfc_constant_result (BT_INTEGER, kind, &e->where);
- rtrunc = gfc_copy_expr (e);
itrunc = gfc_copy_expr (e);
! cmp = mpfr_cmp_ui (e->value.real, 0);
!
! gfc_set_model (e->value.real);
! mpfr_init (half);
! mpfr_set_str (half, "0.5", 10, GFC_RND_MODE);
!
! if (cmp > 0)
! {
! mpfr_add (rtrunc->value.real, e->value.real, half, GFC_RND_MODE);
! mpfr_trunc (itrunc->value.real, rtrunc->value.real);
! }
! else if (cmp < 0)
! {
! mpfr_sub (rtrunc->value.real, e->value.real, half, GFC_RND_MODE);
! mpfr_trunc (itrunc->value.real, rtrunc->value.real);
! }
! else
! mpfr_set_ui (itrunc->value.real, 0, GFC_RND_MODE);
gfc_mpfr_to_mpz (result->value.integer, itrunc->value.real);
gfc_free_expr (itrunc);
- gfc_free_expr (rtrunc);
- mpfr_clear (half);
return range_check (result, name);
}
--- 2390,2402 ----
result = gfc_constant_result (BT_INTEGER, kind, &e->where);
itrunc = gfc_copy_expr (e);
! mpfr_round(itrunc->value.real, e->value.real);
gfc_mpfr_to_mpz (result->value.integer, itrunc->value.real);
gfc_free_expr (itrunc);
return range_check (result, name);
}
program nint_1
if (int(nint(8388609.0)) /= 8388609) call abort
if (int(nint(0.49999997)) /= 0) call abort
end program nint_1