This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gfortran] ping PATCH PR libfortran/20124
- From: FranÃois-Xavier Coudert <Francois-Xavier dot Coudert at lcp dot u-psud dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Cc: gfortran <fortran at gcc dot gnu dot org>
- Date: Thu, 03 Mar 2005 17:59:18 +0100
- Subject: [gfortran] ping PATCH PR libfortran/20124
- Organization: Laboratoire de Chimie Physique
- References: <421E1096.3020605@lcp.u-psud.fr>
This patch fixes PR libfortran/20124. If comes with a nice testcase for
inclusion into gfortran testsuite. Details are the same as last time:
> I would have liked to be able not to use another variable
> (which I called nzero_real), but I couldn't find any simple other way to
> do it. So, we store in nzero_real the number of leading zeros in the
> fractionnal part of the floating point number, whatever the width of the
> format is.
This is *strapped and regtested on i686-linux. I hereby donate this patch to
the FSF.
2005-03-03 Francois-Xavier Coudert <coudert@clipper.ens.fr>
PR libfortran/20124
* write.c (output_float): Adds a nzero_real variable to store
the number of leading zeros whatever the format width is.
Corrects the rounding of numbers less than 10^(-width).
2005-03-03 Francois-Xavier Coudert <coudert@clipper.ens.fr>
PR libfortran/20124
* rounding_zero.f90: New test.
Index: libgfortran/io/write.c
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/io/write.c,v
retrieving revision 1.26
diff -p -u -r1.26 write.c
--- libgfortran/io/write.c 27 Feb 2005 20:11:01 -0000 1.26
+++ libgfortran/io/write.c 3 Mar 2005 16:11:36 -0000
@@ -286,6 +286,8 @@ output_float (fnode *f, double value, in
int nzero;
/* Number of digits after the decimal point. */
int nafter;
+ /* Number of zeros after the decimal point, whatever the precision. */
+ int nzero_real;
int leadzero;
int nblanks;
int i;
@@ -295,6 +297,8 @@ output_float (fnode *f, double value, in
w = f->u.real.w;
d = f->u.real.d;
+ nzero_real = -1;
+
/* We should always know the field width and precision. */
if (d < 0)
internal_error ("Unspecified precision");
@@ -359,6 +363,7 @@ output_float (fnode *f, double value, in
if (nbefore < 0)
{
nzero = -nbefore;
+ nzero_real = nzero;
if (nzero > d)
nzero = d;
nafter = d - nzero;
@@ -436,7 +441,17 @@ output_float (fnode *f, double value, in
/* Round the value. */
if (nbefore + nafter == 0)
+ {
ndigits = 0;
+ if (nzero_real == d && digits[0] >= '5')
+ {
+ /* We rounded to zero but shouldn't have */
+ nzero--;
+ nafter = 1;
+ digits[0] = '1';
+ ndigits = 1;
+ }
+ }
else if (nbefore + nafter < ndigits)
{
ndigits = nbefore + nafter;
! { dg-do run }
character(len=50) c
write(c,'(2f10.2)') -0.01, 0.01
if (trim(adjustl(c)) .ne. "-0.01 0.01") call abort
end