https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93567
--- Comment #3 from Dominique d'Humieres <dominiq at lps dot ens.fr> --- With --- ../_clean/libgfortran/io/write_float.def 2020-06-13 03:11:55.000000000 +0200 +++ libgfortran/io/write_float.def 2020-07-20 18:17:41.000000000 +0200 @@ -990,7 +990,7 @@ determine_en_precision (st_parameter_dt switch (dtp->u.p.current_unit->round_status)\ {\ case ROUND_ZERO:\ - r = sign_bit ? 1.0 : 0.0;\ + r = sign_bit ? -1.0 : 0.0;\ break;\ case ROUND_UP:\ r = 1.0;\ @@ -1004,7 +1004,7 @@ determine_en_precision (st_parameter_dt exp_d = calculate_exp_ ## x (d);\ r_sc = (1 - r / exp_d);\ temp = 0.1 * r_sc;\ - if ((m > 0.0 && ((m < temp) || (r >= (exp_d - m))))\ + if ((m > 0.0 && ((m < temp) || (r > (exp_d - m - sign_bit))))\ || ((m == 0.0) && !(compile_options.allow_std\ & (GFC_STD_F2003 | GFC_STD_F2008)))\ || d == 0)\ the extended test case program test_rug print "(G12.2, a)", 99.0_8, " expected 99." print "(G12.2, a)", 100.0_8, " expected 0.10E+03" print "(RU,G12.2, a)", 99.0_8, " expected 99." print "(RU,G12.2, a)", 99.01_8, " expected 0.10E+03" print "(RU,G12.4,a)", 99.0_8 , " expected 99.00" print "(RU,G12.4,a)", 99.01_8, " expected 99.02" print "(RD,G12.2,a)", 99.0_8, " expected 99." print "(RD,G12.2,a)", 99.01_8, " expected 99." print "(RD,G12.2,a)", -99.0_8, " expected -99." print "(RD,G12.2,a)", -99.01_8, " expected -0.10E+03" print "(RD,G12.2,a)", -100.00_8, " expected -0.10E+03" print "(Rz,G12.2,a)", -99.01_8, " expected -99." print "(Rz,G12.2,a)", -100.01_8, " expected -0.10E+03" end gives the expected results. Note that this "fix" is empirical and I am not 100% convinced it will work for all cases.