aboutsummaryrefslogtreecommitdiff
path: root/libgfortran/io/write.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgfortran/io/write.c')
-rw-r--r--libgfortran/io/write.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index 403b9afe322..d97caec8bc7 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Andy Vaught
This file is part of the GNU Fortran 95 runtime library (libgfortran).
@@ -286,6 +286,8 @@ output_float (fnode *f, double value, int len)
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,9 +297,12 @@ output_float (fnode *f, double value, int len)
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 ("Uspecified precision");
+ internal_error ("Unspecified precision");
/* Use sprintf to print the number in the format +D.DDDDe+ddd
For an N digit exponent, this gives us (32-6)-N digits after the
@@ -359,6 +364,7 @@ output_float (fnode *f, double value, int len)
if (nbefore < 0)
{
nzero = -nbefore;
+ nzero_real = nzero;
if (nzero > d)
nzero = d;
nafter = d - nzero;
@@ -375,7 +381,8 @@ output_float (fnode *f, double value, int len)
case FMT_E:
case FMT_D:
i = g.scale_factor;
- e -= i;
+ if (value != 0.0)
+ e -= i;
if (i < 0)
{
nbefore = 0;
@@ -395,7 +402,7 @@ output_float (fnode *f, double value, int len)
nafter = d;
}
- if (ft = FMT_E)
+ if (ft == FMT_E)
expchar = 'E';
else
expchar = 'D';
@@ -404,7 +411,8 @@ output_float (fnode *f, double value, int len)
case FMT_EN:
/* The exponent must be a multiple of three, with 1-3 digits before
the decimal point. */
- e--;
+ if (value != 0.0)
+ e--;
if (e >= 0)
nbefore = e % 3;
else
@@ -421,7 +429,8 @@ output_float (fnode *f, double value, int len)
break;
case FMT_ES:
- e--;
+ if (value != 0.0)
+ e--;
nbefore = 1;
nzero = 0;
nafter = d;
@@ -435,7 +444,17 @@ output_float (fnode *f, double value, int len)
/* Round the value. */
if (nbefore + nafter == 0)
- ndigits = 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;
@@ -518,7 +537,7 @@ output_float (fnode *f, double value, int len)
/* Pick a field size if none was specified. */
if (w <= 0)
- w = nbefore + nzero + nafter + 2;
+ w = nbefore + nzero + nafter + (sign != SIGN_NONE ? 2 : 1);
/* Create the ouput buffer. */
out = write_block (w);
@@ -655,7 +674,7 @@ static void
write_float (fnode *f, const char *source, int len)
{
double n;
- int nb =0, res;
+ int nb =0, res, save_scale_factor;
char * p, fin;
fnode *f2 = NULL;
@@ -704,8 +723,10 @@ write_float (fnode *f, const char *source, int len)
}
else
{
+ save_scale_factor = g.scale_factor;
f2 = calculate_G_format(f, n, len, &nb);
output_float (f2, n, len);
+ g.scale_factor = save_scale_factor;
if (f2 != NULL)
free_mem(f2);