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