summaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorjvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-01 02:24:50 +0000
committerjvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-01 02:24:50 +0000
commit1955b88d903288c2fa3ec0866051a457cf223ec3 (patch)
tree2f7c101ba68757fd005f51222f82435e62831ff3 /libgfortran
parentaf97728458fa973bc36fa54c55936a44dfb54bad (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--libgfortran/io/write_float.def32
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. */