diff mbox

[libgfortran] PR68867 numeric formatting problem in the fortran library

Message ID 566CF0AF.6060901@charter.net
State New
Headers show

Commit Message

Jerry DeLisle Dec. 13, 2015, 4:14 a.m. UTC
Hi all,

This PR is about different binary precision of quad floats on different platforms.

X86 uses libquadmath with 113 bits, PowerPC uses IBM 106 bits.

For list directed output we set the default decimal precision to use.  Because
the PowerPC has fewer significant bits, we need to adjust the formatting for
kind=16 accordingly or we are just getting junk in the last few digits emitted
(consistent junk).  This patch reduces the width and precision via conditional
compilation depending on the bit precision.

Regression tested on X86_64 and PowerPC (Power7) Linux.  The patch includes the
necessary updates of the testsuite quad_2.f90.

OK for trunk?

Regards,

Jerry

2015-12-12  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libfortran/pr68867
	* io/write.c (set_fnode_default): For kind=16, set the decimal precision
	depending on the platform binary precision, 106 or 113.

Comments

Steve Kargl Dec. 13, 2015, 4:30 a.m. UTC | #1
On Sat, Dec 12, 2015 at 08:14:39PM -0800, Jerry DeLisle wrote:
>      case 16:
> +      /* Adjust decimal precision depending on binary precision, 103 or 113.  */


s/103/106

I suspect that this is simply a bandaid on a much bigger
problem.  Namely, few of the intrinsic functions for 
REAL(16) expect 106 bits instead of 113 bits.
diff mbox

Patch

Index: gcc/testsuite/gfortran.dg/quad_2.f90
===================================================================
--- gcc/testsuite/gfortran.dg/quad_2.f90	(revision 231314)
+++ gcc/testsuite/gfortran.dg/quad_2.f90	(working copy)
@@ -49,18 +49,19 @@  program test_qp
        if (str4 /= "1.41421356237309504876") call abort()
 
      case (16)
-       if (str1 /= "   1.00000000000000000000000000000000000") call abort()
-       if (str2 /= "1.00000000000000000000000000000000000") call abort()
-
        if (digits(1.0_qp) == 113) then
          ! IEEE 754 binary 128 format
          ! e.g. libquadmath/__float128 on i686/x86_64/ia64
+         if (str1 /= "   1.00000000000000000000000000000000000") call abort()
+         if (str2 /= "1.00000000000000000000000000000000000") call abort()
          if (str3 /= "   1.41421356237309504880168872420969798") call abort()
          if (str4 /= "1.41421356237309504880168872420969798") call abort()
        else if (digits(1.0_qp) == 106) then
          ! IBM binary 128 format
-         if (str3(1:37) /= "   1.41421356237309504880168872420969") call abort()
-         if (str4(1:34) /= "1.41421356237309504880168872420969") call abort()
+         if (str1 /= "   1.0000000000000000000000000000000") call abort()
+         if (str2 /= "1.0000000000000000000000000000000") call abort()
+         if (str3(1:37) /= "   1.4142135623730950488016887242097") call abort()
+         if (str4(1:34) /= "1.4142135623730950488016887242097") call abort()
        end if
 
        ! Do a libm run-time test
Index: libgfortran/io/write.c
===================================================================
--- libgfortran/io/write.c	(revision 231314)
+++ libgfortran/io/write.c	(working copy)
@@ -1405,9 +1405,16 @@  set_fnode_default (st_parameter_dt *dtp, fnode *f,
       f->u.real.e = 4;
       break;
     case 16:
+      /* Adjust decimal precision depending on binary precision, 103 or 113.  */
+#if GFC_REAL_16_DIGITS == 113
       f->u.real.w = 45;
       f->u.real.d = 36;
       f->u.real.e = 4;
+#else
+      f->u.real.w = 41;
+      f->u.real.d = 32;
+      f->u.real.e = 4;
+#endif
       break;
     default:
       internal_error (&dtp->common, "bad real kind");