This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Difference between real(kind=16) and long double


Please, don't break gfortran to paper over problems with
darwin (and HPUX).  If these arch have broken long double
or missing/broken C99 math functions, then so be it.  It
seems that you are spending too much time applying wallpaper
for targets with little vendor support.

As far as I can say, this problem is present on all targets that have long doubles made of 2 IEEE doubles, including powerpc and mips processors. It's not a question of target library support, but simply a question of mismatch between the definition of that long double floating-point mode and the definition of the Fortran number model. See below.


Otherwise, I understand your concern of keeping gfortran simple (or at least that's what I think your concern is), but I think we need gfortran to behave correctly (at least in most situations) for a wide range of targets. We are the only compiler that supports such a large range of targets, as well as cross-compilation between them, and that's good. I agree that a balance needs to be kept between range of targets and maintainability, and for this reason I try to keep workarounds self-contained, using autoconf magic and others. If you think they're not enough, please feel free to comment or object to said patches, because I really don't want to hinder gfortran maintainability.

The model numbers and results for the numeric inquiry functions
are generated in arith.c.  The numeric inquiry functions, which
includes HUGE(), are well-defined in the standard.  If FLT_MAX,
DBL_MAX, and LDBL_MAX on a platform do not agree with fortran's
HUGE(), then open a bug report with the vendor.  Their float.h
is broken.

trans-types.c has the following comment:


if (fmt->pnan < fmt->p)
/* This is an IBM extended double format (or the MIPS variant)
made up of two IEEE doubles. The value of the long double is
the sum of the values of the two parts. The most significant
part is required to be the value of the long double rounded
to the nearest double. If we use emax of 1024 then we can't
represent huge(x) = (1 - b**(-p)) * b**(emax-1) * b, because
rounding will make the most significant part overflow. */
gfc_real_kinds[r_index].max_exponent = fmt->emax - 1;


And I finally found the original mailing-list thread about it: http:// gcc.gnu.org/ml/fortran/2005-09/msg00555.html At that time, there seemed to be general agreement that huge(0._16) needn't be the same as LDBL_MAX. So, although I don't agree with your statement quoted above (it's not a vendor bug), I agree with the following (I had to sleep on it):

Under no circumstance should one change (!isfinte(x))
into (!isfinite(x) || x > HUGE || x < HUGE).

That's true. I think the only way to go is to recognize that the Fortran standard doesn't forbid that there can be floating-point numbers larger than HUGE() which aren't Infinities, and as such are not printed out as +Inf. So, it probably means that our implementation is right but we need only fix the testcase.


Opinions welcome, everyone,
FX


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]