diff options
author | jvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-01 02:24:50 +0000 |
---|---|---|
committer | jvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-01 02:24:50 +0000 |
commit | 1955b88d903288c2fa3ec0866051a457cf223ec3 (patch) | |
tree | 2f7c101ba68757fd005f51222f82435e62831ff3 /libgfortran | |
parent | af97728458fa973bc36fa54c55936a44dfb54bad (diff) | |
download | gcc-1955b88d903288c2fa3ec0866051a457cf223ec3.tar.gz |
2011-02-28 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/47567
* io/write_float.def (output_float): Move handling of w = 0 to after
output rounding. Check for zero and set zero_flag accordingly. Set
width according to zero_flag. Add better comments.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@170585 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran')
-rw-r--r-- | libgfortran/ChangeLog | 7 | ||||
-rw-r--r-- | libgfortran/io/write_float.def | 32 |
2 files changed, 25 insertions, 14 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 800c1490bcb..a628fdd8ea1 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,10 @@ +2011-02-28 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR libgfortran/47567 + * io/write_float.def (output_float): Move handling of w = 0 to after + output rounding. Check for zero and set zero_flag accordingly. Set + width according to zero_flag. Add better comments. + 2011-02-27 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libgfortran/47778 diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def index 613ffe0a6be..3709b206620 100644 --- a/libgfortran/io/write_float.def +++ b/libgfortran/io/write_float.def @@ -109,15 +109,7 @@ output_float (st_parameter_dt *dtp, const fnode *f, char *buffer, size_t size, /* Make sure zero comes out as 0.0e0. */ if (zero_flag) - { - e = 0; - if (compile_options.sign_zero != 1) - sign = calculate_sign (dtp, 0); - - /* Handle special cases. */ - if (w == 0) - w = d + (sign != S_NONE ? 2 : 1) + (d == 0 ? 1 : 0); - } + e = 0; /* Normalize the fractional component. */ buffer[2] = buffer[1]; @@ -376,15 +368,21 @@ output_float (st_parameter_dt *dtp, const fnode *f, char *buffer, size_t size, else edigits = 0; - /* Zero values always output as positive, even if the value was negative - before rounding. */ + /* Scan the digits string and count the number of zeros. If we make it + all the way through the loop, we know the value is zero after the + rounding completed above. */ for (i = 0; i < ndigits; i++) { if (digits[i] != '0') break; } + + /* To format properly, we need to know if the rounded result is zero and if + so, we set the zero_flag which may have been already set for + actual zero. */ if (i == ndigits) { + zero_flag = true; /* The output is zero, so set the sign according to the sign bit unless -fno-sign-zero was specified. */ if (compile_options.sign_zero == 1) @@ -393,11 +391,17 @@ output_float (st_parameter_dt *dtp, const fnode *f, char *buffer, size_t size, sign = calculate_sign (dtp, 0); } - /* Pick a field size if none was specified. */ + /* Pick a field size if none was specified, taking into account small + values that may have been rounded to zero. */ if (w <= 0) { - w = nbefore + nzero + nafter + (sign != S_NONE ? 2 : 1); - w = w == 1 ? 2 : w; + if (zero_flag) + w = d + (sign != S_NONE ? 2 : 1) + (d == 0 ? 1 : 0); + else + { + w = nbefore + nzero + nafter + (sign != S_NONE ? 2 : 1); + w = w == 1 ? 2 : w; + } } /* Work out how much padding is needed. */ |