Hi folks,
This patch is a little intrusive and because of the interplay between the
different bugs, I wanted to combine the solution. Thanks to Thomas Henlich for
reporting these bugs and testing.
This patch fixes 48488, 48602 (partially), 48615, and 48684. The adjustments
made require changing several test cases in the testsuite. You may review the
patch to see thos adjustments and what is being done.
The final solution to 48602 I want to do as a second phase to this. The second
phase will attempt to avoid floating point comparisons which are sensitive to
optimizations and or printf behavior.
Regression tested on x86-64. I do have some concern that the test cases modified
may have issues on other platforms because we have increased the default
precision on some reals. If this happens we should be able to adjust test cases
by not using default formatting. The Change Log summarizes. One new test case is
added.
OK for trunk?
Regards,
Jerry
2011-04-24 Jerry DeLisle <jvdeli...@gcc.gnu.org>
PR libgfortran/48488
PR libgfortran/48602
PR libgfortran/48615
PR libgfortran/48684
* io/write.c (set_fnode_default): Adjust default widths to assure
round trip on write and read.
* io/write_float.def (output_float_FMT_G_): Use volatile rather than
asm volatile to avoid optimization issue. Correctly calculate the
number of blanks (nb) to be appended and simplify calculation logic.
(write_float): Increase MIN_FIELD_WIDTH by one to accomodate the new
default widths. Eliminate the code that attempted to reduce the
the precision used in later sprintf functions.
Index: gcc/testsuite/gfortran.dg/fmt_g.f
===================================================================
--- gcc/testsuite/gfortran.dg/fmt_g.f (revision 172909)
+++ gcc/testsuite/gfortran.dg/fmt_g.f (working copy)
@@ -31,13 +31,13 @@
WRITE(buffer,"(G12.5E5,'<')") -10000.
if (buffer.ne."************<") call abort
WRITE(buffer,"(G13.5E5,'<')") -10000.
- if (buffer.ne."-10000. <") call abort
+ if (buffer.ne."*************<") call abort
WRITE(buffer,"(G14.5E5,'<')") -10000.
- if (buffer.ne." -10000. <") call abort
+ if (buffer.ne."-10000. <") call abort
WRITE(buffer,"(G15.5E5,'<')") -10000.
- if (buffer.ne." -10000. <") call abort
+ if (buffer.ne." -10000. <") call abort
WRITE(buffer,"(G16.5E5,'<')") -10000.
- if (buffer.ne." -10000. <") call abort
+ if (buffer.ne." -10000. <") call abort
STOP
END
Index: gcc/testsuite/gfortran.dg/fmt_g0_1.f08
===================================================================
--- gcc/testsuite/gfortran.dg/fmt_g0_1.f08 (revision 172909)
+++ gcc/testsuite/gfortran.dg/fmt_g0_1.f08 (working copy)
@@ -2,19 +2,19 @@
! PR36420 Fortran 2008: g0 edit descriptor
! Test case provided by Jerry DeLisle <jvdeli...@gcc.gnu.org>
character(25) :: string = "(g0,g0,g0)"
- character(33) :: buffer
+ character(50) :: buffer
write(buffer, '(g0,g0,g0)') ':',12340,':'
if (buffer.ne.":12340:") call abort
write(buffer, string) ':',0,':'
if (buffer.ne.":0:") call abort
- write(buffer, string) ':',1.0/3.0,':'
- if (buffer.ne.":.33333334:") call abort
- write(buffer, '(1x,a,g0,a)') ':',1.0/3.0,':'
- if (buffer.ne." :.33333334:") call abort
+ write(buffer, string) ':',1.0_8/3.0_8,':'
+ if (buffer.ne.":.33333333333333331:") call abort
+ write(buffer, '(1x,a,g0,a)') ':',1.0_8/3.0_8,':'
+ if (buffer.ne." :.33333333333333331:") call abort
write(buffer, string) ':',"hello",':'
- if (buffer.ne.":hello:") call abort
+ if (buffer.ne.":hello:") call abort
write(buffer, "(g0,g0,g0,g0)") ':',.true.,.false.,':'
if (buffer.ne.":TF:") call abort
- write(buffer, "(g0,g0,',',g0,g0)") '(',( 1.2345, 2.4567 ),')'
- if (buffer.ne."(1.2345001,2.4567001)") call abort
+ write(buffer, "(g0,g0,',',g0,g0)") '(',( 1.2345_8, 2.4567_8 ),')'
+ if (buffer.ne."(1.2344999999999999,2.4567000000000001)") call abort
end
Index: gcc/testsuite/gfortran.dg/round_3.f08
===================================================================
--- gcc/testsuite/gfortran.dg/round_3.f08 (revision 0)
+++ gcc/testsuite/gfortran.dg/round_3.f08 (revision 0)
@@ -0,0 +1,75 @@
+! { 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") ! 0.2E+01
+ call checkfmt("(RU,1P,E17.0)", 2.5, " 3.E+00")
+ call checkfmt("(RU,ES17.0)", 2.5, " 3.E+00") ! 2.E+00
+ call checkfmt("(RU,EN17.0)", 2.5, " 3.E+00")
+
+ 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") ! 0.2E+01
+ call checkfmt("(RC,1P,E17.0)", 2.5, " 3.E+00")
+ call checkfmt("(RC,ES17.0)", 2.5, " 3.E+00") ! 2.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") ! -0.2E+01
+ call checkfmt("(RC,1P,E17.0)", -2.5, " -3.E+00")
+ call checkfmt("(RC,ES17.0)", -2.5, " -3.E+00") ! -2.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") ! 0.2E+01
+ call checkfmt("(RD,E17.1)", nearest(3.0, -1.0), " 0.2E+01") ! 0.3E+01
+
+contains
+ subroutine checkfmt(fmt, x, cmp)
+ character(len=*), intent(in) :: fmt
+ real, intent(in) :: x
+ character(len=*), intent(in) :: cmp
+ character(len=40) :: 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
Index: gcc/testsuite/gfortran.dg/namelist_print_1.f
===================================================================
--- gcc/testsuite/gfortran.dg/namelist_print_1.f (revision 172909)
+++ gcc/testsuite/gfortran.dg/namelist_print_1.f (working copy)
@@ -9,5 +9,5 @@
namelist /mynml/ x
x = 1
! ( dg-output "^" }
- print mynml ! { dg-output "&MYNML(\n|\r\n|\r) X= 1.0000000 ,(\n|\r\n|\r) /(\n|\r\n|\r)" }
+ print mynml ! { dg-output "&MYNML(\n|\r\n|\r) X= 1.00000000 ,(\n|\r\n|\r) /(\n|\r\n|\r)" }
end
Index: gcc/testsuite/gfortran.dg/char4_iunit_1.f03
===================================================================
--- gcc/testsuite/gfortran.dg/char4_iunit_1.f03 (revision 172909)
+++ gcc/testsuite/gfortran.dg/char4_iunit_1.f03 (working copy)
@@ -5,7 +5,7 @@
! Test case prepared by Jerry DeLisle <jvdeli...@gcc.gnu.org>
program char4_iunit_1
implicit none
- character(kind=4,len=42) :: string
+ character(kind=4,len=44) :: string
integer(kind=4) :: i,j
real(kind=4) :: inf, nan, large
@@ -24,11 +24,11 @@ program char4_iunit_1
write(string, *) .true., .false. , .true.
if (string .ne. 4_" T F T ") call abort
write(string, *) 1.2345e-06, 4.2846e+10_8
- if (string .ne. 4_" 1.23450002E-06 42846000000.000000 ") call abort
+ if (string .ne. 4_" 1.234500019E-06 42846000000.000000 ") call abort
write(string, *) nan, inf
- if (string .ne. 4_" NaN Infinity ") call abort
+ if (string .ne. 4_" NaN Infinity ") call abort
write(string, '(10x,f3.1,3x,f9.1)') nan, inf
- if (string .ne. 4_" NaN Infinity ") call abort
+ if (string .ne. 4_" NaN Infinity ") call abort
write(string, *) (1.2, 3.4 )
- if (string .ne. 4_" ( 1.2000000 , 3.4000001 ) ") call abort
+ if (string .ne. 4_" ( 1.20000005 , 3.40000010 ) ") call abort
end program char4_iunit_1
Index: gcc/testsuite/gfortran.dg/f2003_io_5.f03
===================================================================
--- gcc/testsuite/gfortran.dg/f2003_io_5.f03 (revision 172909)
+++ gcc/testsuite/gfortran.dg/f2003_io_5.f03 (working copy)
@@ -5,7 +5,7 @@ integer :: i
real :: a(10) = [ (i*1.3, i=1,10) ]
real :: b(10)
complex :: c
-character(34) :: complex
+character(36) :: complex
namelist /nm/ a
open(99,file="mynml",form="formatted",decimal="point",status="replace")
@@ -18,9 +18,9 @@ close(99, status="delete")
c = (3.123,4.456)
write(complex,*,decimal="comma") c
-if (complex.ne." ( 3,1229999 ; 4,4559999 )") call abort
+if (complex.ne." ( 3,12299991 ; 4,45599985 )") call abort
c = (0.0, 0.0)
read(complex,*,decimal="comma") c
-if (complex.ne." ( 3,1229999 ; 4,4559999 )") call abort
+if (complex.ne." ( 3,12299991 ; 4,45599985 )") call abort
end
Index: gcc/testsuite/gfortran.dg/coarray_15.f90
===================================================================
--- gcc/testsuite/gfortran.dg/coarray_15.f90 (revision 172909)
+++ gcc/testsuite/gfortran.dg/coarray_15.f90 (working copy)
@@ -9,7 +9,7 @@ program ex2
implicit none
real, allocatable :: z(:)[:]
integer :: image
- character(len=80) :: str
+ character(len=128) :: str
allocate(z(3)[*])
write(*,*) 'z allocated on image',this_image()
@@ -25,18 +25,18 @@ program ex2
str = repeat('X', len(str))
write(str,*) 'z=',z(:),' on image',this_image()
- if (str /= " z= 1.2000000 1.2000000 1.2000000 on image 1") &
- call abort ()
+ if (str /= " z= 1.20000005 1.20000005 1.20000005 on image 1") &
+ call abort
str = repeat('X', len(str))
write(str,*) 'z=',z,' on image',this_image()
- if (str /= " z= 1.2000000 1.2000000 1.2000000 on image 1") &
- call abort ()
+ if (str /= " z= 1.20000005 1.20000005 1.20000005 on image 1") &
+ call abort
str = repeat('X', len(str))
write(str,*) 'z=',z(1:3)[this_image()],' on image',this_image()
- if (str /= " z= 1.2000000 1.2000000 1.2000000 on image 1") &
- call abort ()
+ if (str /= " z= 1.20000005 1.20000005 1.20000005 on image 1") &
+ call abort
call ex2a()
call ex5()
@@ -46,7 +46,7 @@ subroutine ex2a()
implicit none
real, allocatable :: z(:,:)[:,:]
integer :: image
- character(len=100) :: str
+ character(len=128) :: str
allocate(z(2,2)[1,*])
write(*,*) 'z allocated on image',this_image()
@@ -62,38 +62,38 @@ subroutine ex2a()
str = repeat('X', len(str))
write(str,*) 'z=',z(:,:),' on image',this_image()
- if (str /= " z= 1.2000000 1.2000000 1.2000000 1.2000000 on image 1") &
- call abort ()
+ if (str /= " z= 1.20000005 1.20000005 1.20000005 1.20000005 on image 1") &
+ call abort
str = repeat('X', len(str))
write(str,*) 'z=',z,' on image',this_image()
- if (str /= " z= 1.2000000 1.2000000 1.2000000 1.2000000 on image 1") &
- call abort ()
+ if (str /= " z= 1.20000005 1.20000005 1.20000005 1.20000005 on image 1") &
+ call abort
end subroutine ex2a
subroutine ex5
implicit none
integer :: me
real, save :: w(4)[*]
- character(len=100) :: str
+ character(len=128) :: str
me = this_image()
w = me
str = repeat('X', len(str))
write(str,*) 'In main on image',this_image(), 'w= ',w
- if (str /= " In main on image 1 w= 1.0000000 1.0000000 1.0000000 1.0000000") &
- call abort ()
+ if (str /= " In main on image 1 w= 1.00000000 1.00000000 1.00000000 1.00000000") &
+ call abort
str = repeat('X', len(str))
write(str,*) 'In main on image',this_image(), 'w= ',w(1:4)
- if (str /= " In main on image 1 w= 1.0000000 1.0000000 1.0000000 1.0000000") &
- call abort ()
+ if (str /= " In main on image 1 w= 1.00000000 1.00000000 1.00000000 1.00000000") &
+ call abort
str = repeat('X', len(str))
write(str,*) 'In main on image',this_image(), 'w= ',w(:)[1]
- if (str /= " In main on image 1 w= 1.0000000 1.0000000 1.0000000 1.0000000") &
- call abort ()
+ if (str /= " In main on image 1 w= 1.00000000 1.00000000 1.00000000 1.00000000") &
+ call abort
sync all
call ex5_sub(me,w)
@@ -103,10 +103,10 @@ subroutine ex5_sub(n,w)
implicit none
integer :: n
real :: w(n)
- character(len=50) :: str
+ character(len=75) :: str
str = repeat('X', len(str))
write(str,*) 'In sub on image',this_image(), 'w= ',w
- if (str /= " In sub on image 1 w= 1.0000000") &
- call abort ()
+ if (str /= " In sub on image 1 w= 1.00000000") &
+ call abort
end subroutine ex5_sub
Index: gcc/testsuite/gfortran.dg/namelist_65.f90
===================================================================
--- gcc/testsuite/gfortran.dg/namelist_65.f90 (revision 172909)
+++ gcc/testsuite/gfortran.dg/namelist_65.f90 (working copy)
@@ -14,9 +14,9 @@ enddo
write(out,nl1)
if (out(1).ne."&NL1") call abort
-if (out(2).ne." A= 1.0000000 ,") call abort
-if (out(3).ne." B= 2.0000000 ,") call abort
-if (out(4).ne." C= 3.0000000 ,") call abort
+if (out(2).ne." A= 1.00000000 ,") call abort
+if (out(3).ne." B= 2.00000000 ,") call abort
+if (out(4).ne." C= 3.00000000 ,") call abort
if (out(5).ne." /") call abort
end program oneline
Index: gcc/testsuite/gfortran.dg/fmt_cache_1.f
===================================================================
--- gcc/testsuite/gfortran.dg/fmt_cache_1.f (revision 172909)
+++ gcc/testsuite/gfortran.dg/fmt_cache_1.f (working copy)
@@ -3,9 +3,10 @@
! pr40330 incorrect io.
! test case derived from pr40662, <jvdeli...@gcc.gnu.org>
program astap
- character(40) teststring
- arlxca = 0.0
- open(10, status="scratch")
+ implicit none
+ character(34) :: teststring
+ real(4) :: arlxca = 0.0
+ open(10)
write(10,40) arlxca
write(10,40) arlxca
40 format(t4,"arlxca = ",1pg13.6,t27,"arlxcc = ",g13.6,t53,
@@ -21,13 +22,12 @@
. "ebalnc = ",g13.6,t79,"ebalsa = ",g13.6,t105,
. "ebalsc = ",g13.6)
rewind 10
- rewind 10
teststring = ""
read(10,'(a)') teststring
- if (teststring.ne." arlxca = 0.00000 arlxcc = ")call abort
+ if (teststring.ne." arlxca = 0.00000 arlxcc =")call abort
teststring = ""
read(10,'(a)') teststring
- if (teststring.ne." arlxca = 0.00000 arlxcc = ")call abort
+ if (teststring.ne." arlxca = 0.00000 arlxcc =")call abort
end program astap
Index: gcc/testsuite/gfortran.dg/char4_iunit_2.f03
===================================================================
--- gcc/testsuite/gfortran.dg/char4_iunit_2.f03 (revision 172909)
+++ gcc/testsuite/gfortran.dg/char4_iunit_2.f03 (working copy)
@@ -43,5 +43,5 @@ program char4_iunit_2
write(widestring,*)"test",i, x, str_default,&
trim(str_char4)
if (widestring .ne. &
- k_" test 345 52.542999 0 hijklmnp qwertyuiopasd") call abort
+ k_" test 345 52.5429993 0 hijklmnp qwertyuiopasd") call abort
end program char4_iunit_2
Index: gcc/testsuite/gfortran.dg/real_const_3.f90
===================================================================
--- gcc/testsuite/gfortran.dg/real_const_3.f90 (revision 172909)
+++ gcc/testsuite/gfortran.dg/real_const_3.f90 (working copy)
@@ -42,15 +42,15 @@ program main
if (trim(adjustl(str)) .ne. 'NaN') call abort
write(str,*) z
- if (trim(adjustl(str)) .ne. '( NaN, NaN)') call abort
+ if (trim(adjustl(str)) .ne. '( NaN, NaN)') call abort
write(str,*) z2
- if (trim(adjustl(str)) .ne. '( NaN, NaN)') call abort
+ if (trim(adjustl(str)) .ne. '( NaN, NaN)') call abort
write(str,*) z3
- if (trim(adjustl(str)) .ne. '( Infinity, -Infinity)') call abort
+ if (trim(adjustl(str)) .ne. '( Infinity, -Infinity)') call abort
write(str,*) z4
- if (trim(adjustl(str)) .ne. '( 0.0000000 , -0.0000000 )') call abort
+ if (trim(adjustl(str)) .ne. '( 0.00000000 , -0.00000000 )') call abort
end program main
Index: libgfortran/io/write.c
===================================================================
--- libgfortran/io/write.c (revision 172909)
+++ libgfortran/io/write.c (working copy)
@@ -1432,8 +1432,8 @@ set_fnode_default (st_parameter_dt *dtp, fnode *f,
switch (length)
{
case 4:
- f->u.real.w = 15;
- f->u.real.d = 8;
+ f->u.real.w = 16;
+ f->u.real.d = 9;
f->u.real.e = 2;
break;
case 8:
@@ -1442,13 +1442,13 @@ set_fnode_default (st_parameter_dt *dtp, fnode *f,
f->u.real.e = 3;
break;
case 10:
- f->u.real.w = 29;
- f->u.real.d = 20;
+ f->u.real.w = 30;
+ f->u.real.d = 21;
f->u.real.e = 4;
break;
case 16:
- f->u.real.w = 44;
- f->u.real.d = 35;
+ f->u.real.w = 45;
+ f->u.real.d = 36;
f->u.real.e = 4;
break;
default:
Index: libgfortran/io/write_float.def
===================================================================
--- libgfortran/io/write_float.def (revision 172909)
+++ libgfortran/io/write_float.def (working copy)
@@ -864,11 +864,10 @@ output_float_FMT_G_ ## x (st_parameter_dt *dtp, co
\
while (low <= high)\
{ \
- GFC_REAL_ ## x temp;\
+ volatile GFC_REAL_ ## x temp;\
mid = (low + high) / 2;\
\
temp = (calculate_exp_ ## x (mid - 1) * (1 - r * rexp_d));\
- asm volatile ("" : "+m" (temp));\
\
if (m < temp)\
{ \
@@ -894,22 +893,11 @@ output_float_FMT_G_ ## x (st_parameter_dt *dtp, co
}\
}\
\
- if (e > 4)\
- e = 4;\
- if (e < 0)\
- nb = 4;\
- else\
- nb = e + 2;\
-\
- nb = nb >= w ? 0 : nb;\
+ nb = e <= 0 ? 4 : e + 2;\
+ nb = nb >= w ? w - 1 : nb;\
newf->format = FMT_F;\
- newf->u.real.w = f->u.real.w - nb;\
-\
- if (m == 0.0)\
- newf->u.real.d = d - 1;\
- else\
- newf->u.real.d = - (mid - d - 1);\
-\
+ newf->u.real.w = w - nb;\
+ newf->u.real.d = m == 0.0 ? d - 1 : -(mid - d - 1) ;\
dtp->u.p.scale_factor = 0;\
\
finish:\
@@ -931,7 +919,7 @@ output_float_FMT_G_ ## x (st_parameter_dt *dtp, co
gfc_char4_t *p4 = (gfc_char4_t *) p;\
memset4 (p4, pad, nb);\
}\
- else\
+ else \
memset (p, pad, nb);\
}\
}\
@@ -1020,9 +1008,9 @@ write_float (st_parameter_dt *dtp, const fnode *f,
{
#if defined(HAVE_GFC_REAL_16) || __LDBL_DIG__ > 18
-# define MIN_FIELD_WIDTH 48
+# define MIN_FIELD_WIDTH 49
#else
-# define MIN_FIELD_WIDTH 31
+# define MIN_FIELD_WIDTH 32
#endif
#define STR(x) STR1(x)
#define STR1(x) #x
@@ -1039,23 +1027,8 @@ write_float (st_parameter_dt *dtp, const fnode *f,
to handle the largest number of exponent digits expected. */
edigits=4;
- if (f->format == FMT_F || f->format == FMT_EN || f->format == FMT_G
- || ((f->format == FMT_D || f->format == FMT_E)
- && dtp->u.p.scale_factor != 0))
- {
- /* Always convert at full precision to avoid double rounding. */
- ndigits = MIN_FIELD_WIDTH - 4 - edigits;
- }
- else
- {
- /* The number of digits is known, so let printf do the rounding. */
- if (f->format == FMT_ES)
- ndigits = f->u.real.d + 1;
- else
- ndigits = f->u.real.d;
- if (ndigits > MIN_FIELD_WIDTH - 4 - edigits)
- ndigits = MIN_FIELD_WIDTH - 4 - edigits;
- }
+ /* Always convert at full precision to avoid double rounding. */
+ ndigits = MIN_FIELD_WIDTH - 4 - edigits;
switch (len)
{