real128 cmplx ATAN, ATANH - quality of implementation?
Steve Kargl
sgk@troutmask.apl.washington.edu
Fri Feb 3 21:03:00 GMT 2017
On Fri, Feb 03, 2017 at 05:19:51PM +0100, FX wrote:
> > No, it is not. Anton uses x86_64-*-free. REAL128 maps to REAL(10)
> > aka long double complex. Note, that the standard says that REAL128
> > corresponds with a type that occupies 128 bits, which REAL(10) does
> > on FreeBSD (long double is padded for 16-byte alignment).
>
> Even on other platforms it often does. I had forgotten that.
>
I suspect some users will see REAL128 and think that this maps
to an IEEE754-2008 128-bit floating point type with 113-bits of
precisions. This patch will cause gfortran to select the
kind type with the larget precision. Testing on x86_64-*-freebsd
with the following program
program foo
use iso_fortran_env
print '(3(I0,1x))', kind(1._REAL32), kind(1._REAL64), kind(1._REAL128)
end program foo
gives '4 8 10' without the patch and '4 8 16' with the patch.
What do you think? Should we adopt the patch?
Index: gcc/fortran/trans-types.c
===================================================================
--- gcc/fortran/trans-types.c (revision 245068)
+++ gcc/fortran/trans-types.c (working copy)
@@ -234,27 +234,33 @@ gfc_get_int_kind_from_width_isofortranen
return -1;
}
-/* Get the kind number corresponding to a real of given storage size,
- following the required return values for ISO_FORTRAN_ENV REAL* constants:
- -2 is returned if we support a kind of larger size, -1 otherwise. */
+
+/* Get the kind number corresponding to a real of a given storage size.
+ If two real's have the same storage size, then choose the real with
+ the largest precision. If a kind type is unavailable, return -1. */
+
int
gfc_get_real_kind_from_width_isofortranenv (int size)
{
- int i;
+ int digits, i, kind;
size /= 8;
+ kind = -1;
+ digits = 0;
+
/* Look for a kind with matching storage size. */
for (i = 0; gfc_real_kinds[i].kind != 0; i++)
if (int_size_in_bytes (gfc_get_real_type (gfc_real_kinds[i].kind)) == size)
- return gfc_real_kinds[i].kind;
-
- /* Look for a kind with larger storage size. */
- for (i = 0; gfc_real_kinds[i].kind != 0; i++)
- if (int_size_in_bytes (gfc_get_real_type (gfc_real_kinds[i].kind)) > size)
- return -2;
+ {
+ if (gfc_real_kinds[i].digits > digits)
+ {
+ digits = gfc_real_kinds[i].digits;
+ kind = gfc_real_kinds[i].kind;
+ }
+ }
- return -1;
+ return kind;
}
--
Steve
20161221 https://www.youtube.com/watch?v=IbCHE-hONow
More information about the Fortran
mailing list