delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2003/08/18/11:08:51

Date: Mon, 18 Aug 2003 11:21:04 +0300 (EET DST)
From: Esa A E Peuha <peuha AT cc DOT helsinki DOT fi>
Sender: peuha AT sirppi DOT helsinki DOT fi
To: djgpp-workers AT delorie DOT com
Subject: Re: Anomaly in printf()
In-Reply-To: <Pine.OSF.4.51.0308151000100.13877@sirppi.helsinki.fi>
Message-ID: <Pine.OSF.4.51.0308181110430.25551@sirppi.helsinki.fi>
References: <46 DOT 3c4de930 DOT 2c6a2e90 AT aol DOT com> <Pine DOT OSF DOT 4 DOT 51 DOT 0308131046310 DOT 2694 AT sirppi DOT helsinki DOT fi>
<3F3B2D8E DOT F90E84B5 AT phekda DOT freeserve DOT co DOT uk> <7458-Thu14Aug2003112749+0300-eliz AT elta DOT co DOT il>
<Pine DOT OSF DOT 4 DOT 51 DOT 0308151000100 DOT 13877 AT sirppi DOT helsinki DOT fi>
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: djgpp-workers AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

On Fri, 15 Aug 2003, Esa A E Peuha wrote:

> I do. :-)  This is really a classic case of the wrong way to compute
> remainder modulo something; this patch does it the right way:

Actually, it doesn't; if the number is greater than 2^64, this could
put random garbage on the string.  So we need to test the return value
of modfl to see if we can know the digit at all.  This should really do
it right:

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	18 Aug 2003 08:10:15 -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,596 ----
          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)
    {
!     if(modfl(integer / 10.0L , &tmp))
!       *p-- = tochar((int)(integer - (tmp * 10.0L)));
!     else
!       *p-- = '0';
!     integer = tmp;
    }
    switch(fmtch)
    {

-- 
Esa Peuha
student of mathematics at the University of Helsinki
http://www.helsinki.fi/~peuha/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019