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]

[patch, libgfortran] PR32611 Print sign of negative zero


The attached patch provides a solution to this PR.

The patch uses the signbit function to determine if a zero value is negative. If so, the sign is emitted. If -std=legacy is specified at compile time, the negative sign for zero values is not emitted.

This patch requires -std=legacy to be used to pass NIST. This is because F77 explicitly prohibits printing the negative sign for zero values.

No new test cases are required. The patch updates several to reflect the change. One test, pr17706.f90, exercises the legacy behavior.

Regression tested on X86-64-Gnu/Linux.

OK for trunk?

Regards,

Jerry

2007-07-08 Jerry DeLisle <jvdelisle@gcc.gnu.org>

	PR libgfortran/32611
	* io/write.c (output_float): Use the sign bit of the value to determine
	if a negative sign should be emitted for zero values.  Do not emit the
	negative sign for zero if -std=legacy was set during compile.
	
2007-07-08  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libgfortran/32611
	* gfortran.dg/large_real_kind_1.f90: Update test.
	* gfortran.dg/pr17706.f90: Update test.
	* gfortran.dg/fmt_zero_digits.f90: Update test.
	* gfortran.dg/fmt_zero_precision.f90: Update test.
	* gfortran.dg/real_const_3.f90: Update test.
Index: gcc/testsuite/gfortran.dg/large_real_kind_1.f90
===================================================================
--- gcc/testsuite/gfortran.dg/large_real_kind_1.f90	(revision 126472)
+++ gcc/testsuite/gfortran.dg/large_real_kind_1.f90	(working copy)
@@ -67,7 +67,7 @@ program test
 
   x = tiny(x)
   call outputstring (x,'(F20.15)','   0.000000000000000')
-  call outputstring (-x,'(F20.15)','   0.000000000000000')
+  call outputstring (-x,'(F20.15)','  -0.000000000000000')
 
   write (c1,'(G20.10E5)') x
   write (c2,'(G20.10E5)') -x
Index: gcc/testsuite/gfortran.dg/pr17706.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr17706.f90	(revision 126472)
+++ gcc/testsuite/gfortran.dg/pr17706.f90	(working copy)
@@ -1,4 +1,5 @@
 ! { dg-do run }
+! { dg-options "-std=legacy" }
 ! PR17706
 ! this is a libgfortran test
 ! output value -0.00 is not standard compliant
Index: gcc/testsuite/gfortran.dg/fmt_zero_digits.f90
===================================================================
--- gcc/testsuite/gfortran.dg/fmt_zero_digits.f90	(revision 126472)
+++ gcc/testsuite/gfortran.dg/fmt_zero_digits.f90	(working copy)
@@ -6,5 +6,7 @@ program test
   50 FORMAT (d20.0)
   astr = ""
   write(astr,50) -8.0D0
+  if (astr.ne."             -0.D+01") call abort()
+  write(astr,50) 8.0D0
   if (astr.ne."              0.D+01") call abort()
 end program test
Index: gcc/testsuite/gfortran.dg/fmt_zero_precision.f90
===================================================================
--- gcc/testsuite/gfortran.dg/fmt_zero_precision.f90	(revision 126472)
+++ gcc/testsuite/gfortran.dg/fmt_zero_precision.f90	(working copy)
@@ -53,7 +53,7 @@
 ! { dg-output "-1\\.<(\n|\r\n|\r)" }
 ! { dg-output "-1\\.<(\n|\r\n|\r)" }
 ! { dg-output "-1\\.<(\n|\r\n|\r)" }
-! { dg-output " 0\\.<(\n|\r\n|\r)" }
+! { dg-output "-0\\.<(\n|\r\n|\r)" }
 ! { dg-output "     38\\.<(\n|\r\n|\r)" }
 ! { dg-output "  10345\\.<(\n|\r\n|\r)" }
 ! { dg-output "    334\\.<(\n|\r\n|\r)" }
Index: gcc/testsuite/gfortran.dg/real_const_3.f90
===================================================================
--- gcc/testsuite/gfortran.dg/real_const_3.f90	(revision 126472)
+++ gcc/testsuite/gfortran.dg/real_const_3.f90	(working copy)
@@ -38,4 +38,4 @@ end program main
 !{ dg-output " \\(           NaN,           NaN\\)(\n|\r\n|\r)" }
 !{ dg-output " \\(           NaN,           NaN\\)(\n|\r\n|\r)" }
 !{ dg-output " \\(     \\+Infinity,     -Infinity\\)(\n|\r\n|\r)" }
-!{ dg-output " \\(  0.000000    ,  0.000000    \\)(\n|\r\n|\r)" }
+!{ dg-output " \\(  0.000000    , -0.000000    \\)(\n|\r\n|\r)" }
Index: libgfortran/io/write.c
===================================================================
--- libgfortran/io/write.c	(revision 126472)
+++ libgfortran/io/write.c	(working copy)
@@ -465,6 +465,7 @@ output_float (st_parameter_dt *dtp, cons
   int leadzero;
   int nblanks;
   int i;
+  int sign_bit;
   sign_t sign;
 
   ft = f->format;
@@ -482,6 +483,7 @@ output_float (st_parameter_dt *dtp, cons
      For an N digit exponent, this gives us (MIN_FIELD_WIDTH-5)-N digits
      after the decimal point, plus another one before the decimal point.  */
   sign = calculate_sign (dtp, value < 0.0);
+  sign_bit = signbit (value);
   if (value < 0)
     value = -value;
 
@@ -547,9 +549,15 @@ output_float (st_parameter_dt *dtp, cons
   /* Read the exponent back in.  */
   e = atoi (&buffer[ndigits + 3]) + 1;
 
-  /* Make sure zero comes out as 0.0e0.  */
+  /* Make sure zero comes out as 0.0e0.   */
   if (value == 0.0)
-    e = 0;
+    {
+      e = 0;
+      if (compile_options.warn_std != 0)
+        sign = calculate_sign(dtp, sign_bit);
+      else
+	sign = calculate_sign(dtp, 0);
+    }
 
   /* Normalize the fractional component.  */
   buffer[2] = buffer[1];
@@ -751,7 +759,14 @@ output_float (st_parameter_dt *dtp, cons
 	break;
     }
   if (i == ndigits)
-    sign = calculate_sign (dtp, 0);
+    {
+      /* The output is zero, so set the sign according to the sign bit unless
+	 -std=legacy was specified.  */
+      if (compile_options.warn_std != 0)
+        sign = calculate_sign(dtp, sign_bit);
+      else
+	sign = calculate_sign(dtp, 0);
+    }
 
   /* Work out how much padding is needed.  */
   nblanks = w - (nbefore + nzero + nafter + edigits + 1);
@@ -776,7 +791,6 @@ output_float (st_parameter_dt *dtp, cons
 
   /* Pad to full field width.  */
 
-
   if ( ( nblanks > 0 ) && !dtp->u.p.no_leading_blank)
     {
       memset (out, ' ', nblanks);

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