Mail Archives: djgpp-workers/2003/08/15/03:15:18
On Thu, 14 Aug 2003, Eli Zaretskii wrote:
> As I'd expect, FWIW: the problem seems to be that the result of either
> multiplying by 0.1 or dividing by 10 does not have an exact FP
> representation. That is, we are seeing inaccuracies in the last
> significant digit which are to be expected.
>
> I don't know how to fix this without a radical change in the
> algorithm.
I do. :-) This is really a classic case of the wrong way to compute
remainder modulo something; this patch does it the right way:
Index: doprnt.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/doprnt.c,v
retrieving revision 1.16
diff -c -p -r1.16 doprnt.c
*** doprnt.c 30 Jun 2003 20:38:15 -0000 1.16
--- doprnt.c 15 Aug 2003 06:59:23 -0000
*************** cvtl(long double number, int prec, int f
*** 579,594 ****
else doextradps=1;
}
/*
! * get integer portion of number; put into the end of the buffer; the
! * .01 is added for modf(356.0 / 10, &integer) returning .59999999...
* The test p >= startp is due to paranoia: buffer length is guaranteed
* to be large enough, but if tmp is somehow a NaN, this loop could
* eventually blow away the stack.
*/
for (; integer && p >= startp; ++expcnt)
{
! tmp = modfl(integer * 0.1L , &integer);
! *p-- = tochar((int)((tmp + .01L) * 10));
}
switch(fmtch)
{
--- 579,594 ----
else doextradps=1;
}
/*
! * get integer portion of number; put into the end of the buffer.
* The test p >= startp is due to paranoia: buffer length is guaranteed
* to be large enough, but if tmp is somehow a NaN, this loop could
* eventually blow away the stack.
*/
for (; integer && p >= startp; ++expcnt)
{
! modfl(integer / 10.0L , &tmp);
! *p-- = tochar((int)(integer - (tmp * 10.0L)));
! integer = tmp;
}
switch(fmtch)
{
--
Esa Peuha
student of mathematics at the University of Helsinki
http://www.helsinki.fi/~peuha/
- Raw text -