diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2003-02-04 00:29:45 +0300 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2003-02-04 00:29:45 +0300 |
commit | ad36f7d19a9275b4b2faff2c5bedd38a834c5a0a (patch) | |
tree | 8ea27c2a009dca738a859079690f6944394ee9f9 /newlib/libc | |
parent | 153e83c605ece91e9b7e6b15a30591ca218fb9c9 (diff) |
2003-02-03 Jeff Johnston <jjohnstn@redhat.com>
* libc/stdlib/ldtoa.c (_ldtoa_r): Fix code to allocate the format
buffer based on the precision, after we have processed the input value
in a local buffer and know its relative magnitude.
Diffstat (limited to 'newlib/libc')
-rw-r--r-- | newlib/libc/stdlib/ldtoa.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/newlib/libc/stdlib/ldtoa.c b/newlib/libc/stdlib/ldtoa.c index 0e4476e66..80e8750a4 100644 --- a/newlib/libc/stdlib/ldtoa.c +++ b/newlib/libc/stdlib/ldtoa.c @@ -2707,10 +2707,13 @@ _ldtoa_r (struct _reent *ptr, long double d, int mode, int ndigits, int *decpt, unsigned short e[NI]; char *s, *p; int i, j, k; +int orig_ndigits; LDPARMS rnd; LDPARMS *ldp = &rnd; char *outstr; +char outbuf[NDEC + MAX_EXP_DIGITS + 10]; +orig_ndigits = ndigits; rnd.rlast = -1; rnd.rndprc = NBITS; @@ -2748,22 +2751,13 @@ if( mode != 3 ) if( mode == 0 ) ndigits = 20; -/* reentrancy addition to use mprec storage pool */ -/* we want to have enough space to hold the formatted result */ -i = ndigits + (mode == 3 ? (MAX_EXP_DIGITS + 1) : 1); -j = sizeof (__ULong); -for (_REENT_MP_RESULT_K(ptr) = 0; sizeof (_Bigint) - sizeof (__ULong) + j <= i; j <<= 1) - _REENT_MP_RESULT_K(ptr)++; -_REENT_MP_RESULT(ptr) = Balloc (ptr, _REENT_MP_RESULT_K(ptr)); -outstr = (char *)_REENT_MP_RESULT(ptr); - /* This sanity limit must agree with the corresponding one in etoasc, to keep straight the returned value of outexpon. */ if( ndigits > NDEC ) ndigits = NDEC; -etoasc( e, outstr, ndigits, mode, ldp ); -s = outstr; +etoasc( e, outbuf, ndigits, mode, ldp ); +s = outbuf; if( eisinf(e) || eisnan(e) ) { *decpt = 9999; @@ -2774,7 +2768,7 @@ if( eisinf(e) || eisnan(e) ) /* Transform the string returned by etoasc into what the caller wants. */ /* Look for decimal point and delete it from the string. */ -s = outstr; +s = outbuf; while( *s != '\0' ) { if( *s == '.' ) @@ -2795,19 +2789,19 @@ while( *s != '\0' ) nodecpt: /* Back up over the exponent field. */ -while( *s != 'E' && s > outstr) +while( *s != 'E' && s > outbuf) --s; *s = '\0'; stripspaces: /* Strip leading spaces and sign. */ -p = outstr; +p = outbuf; while( *p == ' ' || *p == '-') ++p; /* Find new end of string. */ -s = outstr; +s = outbuf; while( (*s++ = *p++) != '\0' ) ; --s; @@ -2820,20 +2814,38 @@ else if( ndigits > ldp->outexpon ) else k = ldp->outexpon; -while( *(s-1) == '0' && ((s - outstr) > k)) +while( *(s-1) == '0' && ((s - outbuf) > k)) *(--s) = '\0'; /* In f format, flush small off-scale values to zero. Rounding has been taken care of by etoasc. */ if( mode == 3 && ((ndigits + ldp->outexpon) < 0)) { - s = outstr; + s = outbuf; *s = '\0'; *decpt = 0; } +/* reentrancy addition to use mprec storage pool */ +/* we want to have enough space to hold the formatted result */ + +if (mode == 3) /* f format, account for sign + dec digits + decpt + frac */ + i = *decpt + orig_ndigits + 3; +else /* account for sign + max precision digs + E + exp sign + exponent */ + i = orig_ndigits + MAX_EXP_DIGITS + 4; + +j = sizeof (__ULong); +for (_REENT_MP_RESULT_K(ptr) = 0; sizeof (_Bigint) - sizeof (__ULong) + j <= i; j <<= 1) + _REENT_MP_RESULT_K(ptr)++; +_REENT_MP_RESULT(ptr) = Balloc (ptr, _REENT_MP_RESULT_K(ptr)); + +/* Copy from internal temporary buffer to permanent buffer. */ +outstr = (char *)_REENT_MP_RESULT(ptr); +strcpy (outstr, outbuf); + if( rve ) - *rve = s; + *rve = outstr + (s - outbuf); + return outstr; } |