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