Comments
Patch
===================================================================
@@ -221,6 +221,7 @@ output_float (st_parameter_dt *dtp, const fnode *f
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
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
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
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:
Hi Folks, This patch fixes the latest 'round' of test cases from Thomas. The patch adjusts the count of digits before the decimal point by one where w>0 and d==0. The patch also consolidates some of the code as a clean up. Regression tested on x86-64. Revised test case attached. OK for trunk? Jerry 2011-05-03 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. ! { dg-do run } ! PR48615 Invalid UP/DOWN rounding with E and ES descriptors ! Test case provided by Thomas Henlich. program pr48615 call checkfmt("(RU,F17.0)", 2.5, " 3.") call checkfmt("(RU,-1P,F17.1)", 2.5, " 0.3") call checkfmt("(RU,E17.1)", 2.5, " 0.3E+01") call checkfmt("(RU,1P,E17.0)", 2.5, " 3.E+00") call checkfmt("(RU,ES17.0)", 2.5, " 3.E+00") call checkfmt("(RU,EN17.0)", 2.5, " 3.E+00") call checkfmt("(RU,F2.0)", 2.0, "2.") call checkfmt("(RU,F6.4)", 2.0, "2.0000") call checkfmt("(RU,1P,E6.0E2)", 2.0, "2.E+00") call checkfmt("(RU,1P,E7.1E2)", 2.5, "2.5E+00") call checkfmt("(RU,1P,E10.4E2)", 2.5, "2.5000E+00") call checkfmt("(RU,1P,G6.0E2)", 2.0, "2.E+00") call checkfmt("(RU,1P,G10.4E2)", 2.3456e5, "2.3456E+05") call checkfmt("(RU,F2.0)", 0.09, "1.") ! 0. call checkfmt("(RD,F3.0)", -0.09, "-1.") ! -0. call checkfmt("(RU,F2.0)", 2.0, "2.") ! 3. call checkfmt("(RD,F3.0)", -2.0, "-2.") ! -3. call checkfmt("(RU,F6.4)", 2.0, "2.0000") ! 2.0001 call checkfmt("(RD,F7.4)", -2.0, "-2.0000") ! -2.0001 call checkfmt("(RU,1P,E6.0E2)", 2.0, "2.E+00") ! 3.E+00 call checkfmt("(RD,1P,E7.0E2)", -2.0, "-2.E+00") ! -3.E+00 call checkfmt("(RU,1P,E7.1E2)", 2.5, "2.5E+00") ! 2.6E+00 call checkfmt("(RD,1P,E8.1E2)", -2.5, "-2.5E+00") ! -2.6E+00 call checkfmt("(RU,1P,E10.4E2)", 2.5, "2.5000E+00") ! 2.5001E+00 call checkfmt("(RD,1P,E11.4E2)", -2.5, "-2.5000E+00") ! -2.5001E+00 call checkfmt("(RU,1P,G6.0E2)", 2.0, "2.E+00") ! 3.E+00 call checkfmt("(RD,1P,G7.0E2)", -2.0, "-2.E+00") ! -3.E+00 call checkfmt("(RU,1P,G10.4E2)", 2.3456e5, "2.3456E+05") ! 2.3457E+05 call checkfmt("(RD,1P,G11.4E2)", -2.3456e5, "-2.3456E+05") ! -2.3457E+05 call checkfmt("(RD,F17.0)", 2.5, " 2.") call checkfmt("(RD,-1P,F17.1)", 2.5, " 0.2") call checkfmt("(RD,E17.1)", 2.5, " 0.2E+01") call checkfmt("(RD,1P,E17.0)", 2.5, " 2.E+00") call checkfmt("(RD,ES17.0)", 2.5, " 2.E+00") call checkfmt("(RD,EN17.0)", 2.5, " 2.E+00") call checkfmt("(RC,F17.0)", 2.5, " 3.") call checkfmt("(RC,-1P,F17.1)", 2.5, " 0.3") call checkfmt("(RC,E17.1)", 2.5, " 0.3E+01") call checkfmt("(RC,1P,E17.0)", 2.5, " 3.E+00") call checkfmt("(RC,ES17.0)", 2.5, " 3.E+00") call checkfmt("(RC,EN17.0)", 2.5, " 3.E+00") call checkfmt("(RN,F17.0)", 2.5, " 2.") call checkfmt("(RN,-1P,F17.1)", 2.5, " 0.2") call checkfmt("(RN,E17.1)", 2.5, " 0.2E+01") call checkfmt("(RN,1P,E17.0)", 2.5, " 2.E+00") call checkfmt("(RN,ES17.0)", 2.5, " 2.E+00") call checkfmt("(RN,EN17.0)", 2.5, " 2.E+00") call checkfmt("(RZ,F17.0)", 2.5, " 2.") call checkfmt("(RZ,-1P,F17.1)", 2.5, " 0.2") call checkfmt("(RZ,E17.1)", 2.5, " 0.2E+01") call checkfmt("(RZ,1P,E17.0)", 2.5, " 2.E+00") call checkfmt("(RZ,ES17.0)", 2.5, " 2.E+00") call checkfmt("(RZ,EN17.0)", 2.5, " 2.E+00") call checkfmt("(RZ,F17.0)", -2.5, " -2.") call checkfmt("(RZ,-1P,F17.1)", -2.5, " -0.2") call checkfmt("(RZ,E17.1)", -2.5, " -0.2E+01") call checkfmt("(RZ,1P,E17.0)", -2.5, " -2.E+00") call checkfmt("(RZ,ES17.0)", -2.5, " -2.E+00") call checkfmt("(RZ,EN17.0)", -2.5, " -2.E+00") call checkfmt("(RN,F17.0)", -2.5, " -2.") call checkfmt("(RN,-1P,F17.1)", -2.5, " -0.2") call checkfmt("(RN,E17.1)", -2.5, " -0.2E+01") call checkfmt("(RN,1P,E17.0)", -2.5, " -2.E+00") call checkfmt("(RN,ES17.0)", -2.5, " -2.E+00") call checkfmt("(RN,EN17.0)", -2.5, " -2.E+00") call checkfmt("(RC,F17.0)", -2.5, " -3.") call checkfmt("(RC,-1P,F17.1)", -2.5, " -0.3") call checkfmt("(RC,E17.1)", -2.5, " -0.3E+01") call checkfmt("(RC,1P,E17.0)", -2.5, " -3.E+00") call checkfmt("(RC,ES17.0)", -2.5, " -3.E+00") call checkfmt("(RC,EN17.0)", -2.5, " -3.E+00") call checkfmt("(RU,E17.1)", nearest(2.0, 1.0), " 0.3E+01") call checkfmt("(RD,E17.1)", nearest(3.0, -1.0), " 0.2E+01") contains subroutine checkfmt(fmt, x, cmp) character(len=*), intent(in) :: fmt real, intent(in) :: x character(len=*), intent(in) :: cmp character(len=20) :: s write(s, fmt) x if (s /= cmp) call abort !if (s /= cmp) print "(a,1x,a,' expected: ',1x)", fmt, s, cmp end subroutine end program