Expected precision of Fortran FE constant evaluation
Steve Kargl
sgk@troutmask.apl.washington.edu
Sat Feb 9 21:00:00 GMT 2019
On Sat, Feb 09, 2019 at 10:45:43PM +0200, Janne Blomqvist wrote:
> On Fri, Feb 8, 2019 at 6:17 PM Jakub Jelinek <jakub@redhat.com> wrote:
>
> > On Fri, Feb 08, 2019 at 05:08:27PM +0100, Richard Biener wrote:
> > > The path affects all mpfr operations including constant folding done by
> > > the frontend. The question is whether the Fortran standard mandates this
> > > excess precision when constant folding (and/or requires constant folding)
> > > or if it merely allows it and the current behavior can be changed without
> > > affecting conformance.
> >
> > Yeah, or worded another way, should gfc_range_check be performed on every
> > arithmetic operation while evaluating the whole expression, or just at the
> > end? The above, if it is done with infinite precision for temporary
> > computations and only range checked at the end will pass, I believe it
> > shouldn't pass if every arithmetic computation is forced to be in the
> > the corresponding kind's type. Bet it is similar to 387 excess precision,
> > but in this case the testcase doesn't expect just slightly bigger
> > precision,
> > but more something like twice as large maximum exponent (i.e. huge*huge
> > still finite). Now, if you compute it at runtime, say using double, it
> > will
> > of course be infinite.
> >
>
> The Fortran standard doesn't specify in which order an expression is
> evaluated, so intermediates in an expression might or might not overflow
> depending on the order of evaluation (say, "a + b - c", if all numbers are
> slightly above HUGE()/2). AFAIK the rules for compile-time evaluation are
> no different than for runtime. So from that perspective it seems better to
> me to range check only the results, and not every intermediate value,
> although AFAICT both are standard conforming.
>
You're correct in that Fortran does not mandate anything about
order of evaluation. gfortran does left to right, and range
check the intermediate values in the evaluation of the RHS.
print *, (huge(1.) / 1.9) + (huge(1.) / 1.9) - (huge(1.) / 1.9)
print *, (huge(1.) / 1.9) + ((huge(1.) / 1.9) - (huge(1.) / 1.9))
end
The first line causes an error. The second line produces 1.79095E38.
--
Steve
More information about the Fortran
mailing list