This is the mail archive of the
newlib@sources.redhat.com
mailing list for the newlib project.
newlib printf %f BUG
- From: Ted Merrill <ted at arraycomm dot com>
- To: newlib at sourceware dot cygnus dot com, jjohnstn at redhat dot com
- Cc: Ted Merrill <ted at arraycomm dot com>
- Date: Mon, 19 Nov 2001 20:09:03 -0800 (PST)
- Subject: newlib printf %f BUG
I hope this is where to report bugs.
Using both newlib-1.8.2 and newlib-1.9.0 compiled using gcc for ARM/thumb
architecture using gcc 3.0,
a bug in printf floating point formatting is seen for some numbers.
Sample code:
void MathTest2(void)
{
/* This tests a bug we found in newlib 1.8.2
*/
double R = 3.4263125;
printf("%.6f\n", R );
}
R is printed as: 4.5373:7
which is not at all the right answer.
NOTE the colon; this is the ascii character following '9'
which should give some clue.
The correct answer is 3.426312 or perhaps maybe 3.426313;
we are at the rounding boundary
when rounding to 6 digits after decimal place.
Apparently the rounding goes haywire?
Info from gcc -v :
Reading specs from /s/wdsl/i/bin.sun5/arm.gcc/specs
Configured with: /s/home/ted/tool.1/i/include/gcc-3.0-acom.1/configure --host=sparc-sun-solaris2.5.1 --prefix=/s/home/ted/_tool/_gccarm/junk.i/sun5-arm --srcdir=/s/home/ted/tool.1/i/include/gcc-3.0-acom.1 --target=arm-ecos-elf --enable-languages=c --with-headers=/s/home/ted/_tool/_gccarm/oo/include/arm.usr.include --with-libs=/s/home/ted/_tool/_gccarm/oo/lib.arm/arm.usr.lib
Thread model: single
gcc version 3.0
Has this bug been spotted by someone else? Any fix?
Thanks.
- Ted Merrill, ArrayComm, Inc.
p.s.
I'm attempt to find (and fix) the problem in the newlib source code.
Things go well until line 517 of stdlib/dtoa.c
where the following code appears:
if (d.d > 0.5 + eps.d)
goto bump_up;
else if (d.d < 0.5 - eps.d)
{
while (*--s == '0');
s++;
goto ret1;
}
break;
d.d at this point is .499999...something and doesn't fall into either
camp... so it falls through to a label "fast_failed" and from there
rapidly down to line 811 where I confess i lose what the algorithm
is trying to do... although clearly at this point it is generating the
wrong answer that i see printed.
Not being too concerned with having exactly the right rounding, i've
simply changed the code above to:
// LESS PRECISE BUT WORKING CODE
if (d.d >= 0.5 )
goto bump_up;
else
{
while (*--s == '0');
s++;
goto ret1;
}