diff options
Diffstat (limited to 'libgfortran/io/write.c')
-rw-r--r-- | libgfortran/io/write.c | 39 |
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); |