diff options
author | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2011-05-05 01:19:30 +0000 |
---|---|---|
committer | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2011-05-05 01:19:30 +0000 |
commit | d6b872ad5e5461b690e76fba943a1d28c27af301 (patch) | |
tree | 236b42840d3e2743ad9a751a7e8f9b567fd5a53d | |
parent | c5c04a8fd89112435221124534214530d9121cc3 (diff) | |
download | gcc-d6b872ad5e5461b690e76fba943a1d28c27af301.zip gcc-d6b872ad5e5461b690e76fba943a1d28c27af301.tar.gz gcc-d6b872ad5e5461b690e76fba943a1d28c27af301.tar.bz2 |
re PR libfortran/48787 (Invalid UP/DOWN rounding with F editing)
2011-05-04 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/48787
* io/write_float.def (output_float): Adjust up and down rounding for
cases where 'd' = 0. Gather common code to one location.
From-SVN: r173408
-rw-r--r-- | libgfortran/ChangeLog | 6 | ||||
-rw-r--r-- | libgfortran/io/write_float.def | 30 |
2 files changed, 24 insertions, 12 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 5b737225..7e081cc 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,9 @@ +2011-05-04 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR libgfortran/48787 + * io/write_float.def (output_float): Adjust up and down rounding for + cases where 'd' = 0. Gather common code to one location. + 2011-05-01 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libgfortran/48787 diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def index 7f3cedd..7ab70d2 100644 --- a/libgfortran/io/write_float.def +++ b/libgfortran/io/write_float.def @@ -221,6 +221,7 @@ output_float (st_parameter_dt *dtp, const fnode *f, char *buffer, size_t size, if (zero_flag) goto skip; + /* Round the value. The value being rounded is an unsigned magnitude. The ROUND_COMPATIBLE is rounding away from zero when there is a tie. */ switch (dtp->u.p.current_unit->round_status) @@ -230,19 +231,11 @@ output_float (st_parameter_dt *dtp, const fnode *f, char *buffer, size_t size, case ROUND_UP: if (sign_bit) goto skip; - rchar = '0'; - /* Scan for trailing zeros to see if we really need to round it. */ - for(i = nbefore + nafter; i < ndigits; i++) - { - if (digits[i] != '0') - goto do_rnd; - } - goto skip; + goto updown; case ROUND_DOWN: if (!sign_bit) goto skip; - rchar = '0'; - break; + goto updown; case ROUND_NEAREST: /* Round compatible unless there is a tie. A tie is a 5 with all trailing zero's. */ @@ -254,7 +247,7 @@ output_float (st_parameter_dt *dtp, const fnode *f, char *buffer, size_t size, if (digits[i] != '0') goto do_rnd; } - /* It is a tie so round to even. */ + /* It is a tie so round to even. */ switch (digits[nafter + nbefore - 1]) { case '1': @@ -274,8 +267,21 @@ output_float (st_parameter_dt *dtp, const fnode *f, char *buffer, size_t size, case ROUND_UNSPECIFIED: case ROUND_COMPATIBLE: rchar = '5'; - /* Just fall through and do the actual rounding. */ + goto do_rnd; + } + + updown: + + rchar = '0'; + if (w > 0 && d == 0 && p == 0) + nbefore = 1; + /* Scan for trailing zeros to see if we really need to round it. */ + for(i = nbefore + nafter; i < ndigits; i++) + { + if (digits[i] != '0') + goto do_rnd; } + goto skip; do_rnd: |