From d6b872ad5e5461b690e76fba943a1d28c27af301 Mon Sep 17 00:00:00 2001 From: Jerry DeLisle Date: Thu, 5 May 2011 01:19:30 +0000 Subject: [PATCH] re PR libfortran/48787 (Invalid UP/DOWN rounding with F editing) 2011-05-04 Jerry DeLisle 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 --- libgfortran/ChangeLog | 6 ++++++ libgfortran/io/write_float.def | 30 ++++++++++++++++++------------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 5b73722581c..7e081ccf83b 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,9 @@ +2011-05-04 Jerry DeLisle + + 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 PR libgfortran/48787 diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def index 7f3cedd1034..7ab70d28200 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: -- 2.30.2