14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*8462SApril.Chin@Sun.COM * Copyright (c) 1985-2008 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 7*8462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * Glenn Fowler <gsf@research.att.com> * 184887Schin * David Korn <dgk@research.att.com> * 194887Schin * Phong Vo <kpv@research.att.com> * 204887Schin * * 214887Schin ***********************************************************************/ 22*8462SApril.Chin@Sun.COM #if __STDC__ 23*8462SApril.Chin@Sun.COM #include "FEATURE/isoc99" 24*8462SApril.Chin@Sun.COM #endif 254887Schin #include "sfhdr.h" 264887Schin 274887Schin /* Convert a floating point value to ASCII. 284887Schin ** 294887Schin ** Written by Kiem-Phong Vo and Glenn Fowler (SFFMT_AFORMAT) 304887Schin */ 314887Schin 324887Schin static char *lc_inf = "inf", *uc_inf = "INF"; 334887Schin static char *lc_nan = "nan", *uc_nan = "NAN"; 344887Schin static char *Zero = "0"; 354887Schin #define SF_INF ((_Sfi = 3), strncpy(buf, (format & SFFMT_UPPER) ? uc_inf : lc_inf, size)) 364887Schin #define SF_NAN ((_Sfi = 3), strncpy(buf, (format & SFFMT_UPPER) ? uc_nan : lc_nan, size)) 374887Schin #define SF_ZERO ((_Sfi = 1), strncpy(buf, Zero, size)) 384887Schin #define SF_INTPART (SF_IDIGITS/2) 394887Schin 404887Schin #if ! _lib_isnan 414887Schin #if _lib_fpclassify 424887Schin #define isnan(n) (fpclassify(n)==FP_NAN) 434887Schin #define isnanl(n) (fpclassify(n)==FP_NAN) 444887Schin #else 454887Schin #define isnan(n) (memcmp((void*)&n,(void*)&_Sfdnan,sizeof(n))==0) 464887Schin #define isnanl(n) (memcmp((void*)&n,(void*)&_Sflnan,sizeof(n))==0) 474887Schin #endif 484887Schin #else 494887Schin #if ! _lib_isnanl 504887Schin #define isnanl(n) isnan(n) 514887Schin #endif 524887Schin #endif 534887Schin 54*8462SApril.Chin@Sun.COM #if ! _lib_signbit && defined(signbit) 55*8462SApril.Chin@Sun.COM #undef _lib_signbit 56*8462SApril.Chin@Sun.COM #define _lib_signbit 1 57*8462SApril.Chin@Sun.COM #endif 58*8462SApril.Chin@Sun.COM 59*8462SApril.Chin@Sun.COM #if ! _lib_signbit 60*8462SApril.Chin@Sun.COM #if ! _ast_fltmax_double 61*8462SApril.Chin@Sun.COM static int neg0ld(Sfdouble_t f) 62*8462SApril.Chin@Sun.COM { 63*8462SApril.Chin@Sun.COM Sfdouble_t z = -0.0; 64*8462SApril.Chin@Sun.COM return !memcmp(&f, &z, sizeof(f)); 65*8462SApril.Chin@Sun.COM } 66*8462SApril.Chin@Sun.COM #endif 67*8462SApril.Chin@Sun.COM static int neg0d(double f) 68*8462SApril.Chin@Sun.COM { 69*8462SApril.Chin@Sun.COM double z = -0.0; 70*8462SApril.Chin@Sun.COM return !memcmp(&f, &z, sizeof(f)); 71*8462SApril.Chin@Sun.COM } 72*8462SApril.Chin@Sun.COM #endif 73*8462SApril.Chin@Sun.COM 74*8462SApril.Chin@Sun.COM #if ULONG_DIG && ULONG_DIG < (DBL_DIG-1) 75*8462SApril.Chin@Sun.COM #define CVT_LDBL_INT long 76*8462SApril.Chin@Sun.COM #define CVT_LDBL_MAXINT LONG_MAX 77*8462SApril.Chin@Sun.COM #else 78*8462SApril.Chin@Sun.COM #if UINT_DIG && UINT_DIG < (DBL_DIG-1) 79*8462SApril.Chin@Sun.COM #define CVT_LDBL_INT int 80*8462SApril.Chin@Sun.COM #define CVT_LDBL_MAXINT INT_MAX 81*8462SApril.Chin@Sun.COM #else 82*8462SApril.Chin@Sun.COM #define CVT_LDBL_INT long 83*8462SApril.Chin@Sun.COM #define CVT_LDBL_MAXINT SF_MAXLONG 84*8462SApril.Chin@Sun.COM #endif 85*8462SApril.Chin@Sun.COM #endif 86*8462SApril.Chin@Sun.COM 87*8462SApril.Chin@Sun.COM #if ULONG_DIG && ULONG_DIG < (DBL_DIG-1) 88*8462SApril.Chin@Sun.COM #define CVT_DBL_INT long 89*8462SApril.Chin@Sun.COM #define CVT_DBL_MAXINT LONG_MAX 90*8462SApril.Chin@Sun.COM #else 91*8462SApril.Chin@Sun.COM #if UINT_DIG && UINT_DIG < (DBL_DIG-1) 92*8462SApril.Chin@Sun.COM #define CVT_DBL_INT int 93*8462SApril.Chin@Sun.COM #define CVT_DBL_MAXINT INT_MAX 94*8462SApril.Chin@Sun.COM #else 95*8462SApril.Chin@Sun.COM #define CVT_DBL_INT long 96*8462SApril.Chin@Sun.COM #define CVT_DBL_MAXINT SF_MAXLONG 97*8462SApril.Chin@Sun.COM #endif 98*8462SApril.Chin@Sun.COM #endif 99*8462SApril.Chin@Sun.COM 1004887Schin #if __STD_C 101*8462SApril.Chin@Sun.COM char* _sfcvt(Void_t* vp, char* buf, size_t size, int n_digit, 1024887Schin int* decpt, int* sign, int* len, int format) 1034887Schin #else 104*8462SApril.Chin@Sun.COM char* _sfcvt(vp,buf,size,n_digit,decpt,sign,len,format) 105*8462SApril.Chin@Sun.COM Void_t* vp; /* pointer to value to convert */ 1064887Schin char* buf; /* conversion goes here */ 1074887Schin size_t size; /* size of buf */ 1084887Schin int n_digit; /* number of digits wanted */ 1094887Schin int* decpt; /* to return decimal point */ 1104887Schin int* sign; /* to return sign */ 1114887Schin int* len; /* return string length */ 1124887Schin int format; /* conversion format */ 1134887Schin #endif 1144887Schin { 1154887Schin reg char *sp; 1164887Schin reg long n, v; 1174887Schin reg char *ep, *b, *endsp; 1184887Schin _ast_flt_unsigned_max_t m; 1194887Schin 1204887Schin static char lx[] = "0123456789abcdef"; 1214887Schin static char ux[] = "0123456789ABCDEF"; 1224887Schin 1234887Schin *sign = *decpt = 0; 1244887Schin 1254887Schin #if !_ast_fltmax_double 1264887Schin if(format&SFFMT_LDOUBLE) 127*8462SApril.Chin@Sun.COM { Sfdouble_t f = *(Sfdouble_t*)vp; 128*8462SApril.Chin@Sun.COM 129*8462SApril.Chin@Sun.COM if(isnanl(f)) 130*8462SApril.Chin@Sun.COM { 1314887Schin #if _lib_signbit 132*8462SApril.Chin@Sun.COM if (signbit(f)) 1334887Schin #else 134*8462SApril.Chin@Sun.COM if (f < 0) 135*8462SApril.Chin@Sun.COM #endif 136*8462SApril.Chin@Sun.COM *sign = 1; 137*8462SApril.Chin@Sun.COM return SF_NAN; 138*8462SApril.Chin@Sun.COM } 139*8462SApril.Chin@Sun.COM #if _lib_isinf 140*8462SApril.Chin@Sun.COM if (n = isinf(f)) 141*8462SApril.Chin@Sun.COM { 142*8462SApril.Chin@Sun.COM #if _lib_signbit 143*8462SApril.Chin@Sun.COM if (signbit(f)) 1444887Schin #else 145*8462SApril.Chin@Sun.COM if (n < 0 || f < 0) 146*8462SApril.Chin@Sun.COM #endif 147*8462SApril.Chin@Sun.COM *sign = 1; 148*8462SApril.Chin@Sun.COM return SF_INF; 149*8462SApril.Chin@Sun.COM } 150*8462SApril.Chin@Sun.COM #endif 151*8462SApril.Chin@Sun.COM # if _c99_in_the_wild 152*8462SApril.Chin@Sun.COM # if _lib_signbit 153*8462SApril.Chin@Sun.COM if (signbit(f)) 154*8462SApril.Chin@Sun.COM # else 155*8462SApril.Chin@Sun.COM # if _lib_copysignl 156*8462SApril.Chin@Sun.COM if (copysignl(1.0, f) < 0.0) 157*8462SApril.Chin@Sun.COM # else 158*8462SApril.Chin@Sun.COM # if _lib_copysign 1594887Schin if (copysign(1.0, (double)f) < 0.0) 160*8462SApril.Chin@Sun.COM # else 1614887Schin if (f < 0.0) 162*8462SApril.Chin@Sun.COM # endif 163*8462SApril.Chin@Sun.COM # endif 164*8462SApril.Chin@Sun.COM # endif 1654887Schin { f = -f; 1664887Schin *sign = 1; 1674887Schin } 168*8462SApril.Chin@Sun.COM # if _lib_fpclassify 1694887Schin switch (fpclassify(f)) 1704887Schin { 1714887Schin case FP_INFINITE: 1724887Schin return SF_INF; 1734887Schin case FP_NAN: 1744887Schin return SF_NAN; 1754887Schin case FP_ZERO: 1764887Schin return SF_ZERO; 1774887Schin } 178*8462SApril.Chin@Sun.COM # endif 179*8462SApril.Chin@Sun.COM # else 180*8462SApril.Chin@Sun.COM # if _lib_signbit 181*8462SApril.Chin@Sun.COM if (signbit(f)) 182*8462SApril.Chin@Sun.COM # else 183*8462SApril.Chin@Sun.COM if (f < 0.0 || f == 0.0 && neg0ld(f)) 184*8462SApril.Chin@Sun.COM # endif 1854887Schin { f = -f; 1864887Schin *sign = 1; 1874887Schin } 188*8462SApril.Chin@Sun.COM # endif 1894887Schin if(f < LDBL_MIN) 1904887Schin return SF_ZERO; 1914887Schin if(f > LDBL_MAX) 1924887Schin return SF_INF; 1934887Schin 1944887Schin if(format & SFFMT_AFORMAT) 1954887Schin { Sfdouble_t g; 1964887Schin int x; 1974887Schin b = sp = buf; 1984887Schin ep = (format & SFFMT_UPPER) ? ux : lx; 1994887Schin if(n_digit <= 0 || n_digit >= (size - 9)) 2004887Schin n_digit = size - 9; 2014887Schin endsp = sp + n_digit + 1; 2024887Schin 2034887Schin g = frexpl(f, &x); 2044887Schin *decpt = x; 2054887Schin f = ldexpl(g, 8 * sizeof(m) - 3); 2064887Schin 2074887Schin for (;;) 2084887Schin { m = f; 2094887Schin x = 8 * sizeof(m); 2104887Schin while ((x -= 4) >= 0) 2114887Schin { *sp++ = ep[(m >> x) & 0xf]; 2124887Schin if (sp >= endsp) 2134887Schin { ep = sp + 1; 2144887Schin goto done; 2154887Schin } 2164887Schin } 2174887Schin f -= m; 2184887Schin f = ldexpl(f, 8 * sizeof(m)); 2194887Schin } 2204887Schin } 2214887Schin 2224887Schin n = 0; 223*8462SApril.Chin@Sun.COM if(f >= (Sfdouble_t)CVT_LDBL_MAXINT) 2244887Schin { /* scale to a small enough number to fit an int */ 2254887Schin v = SF_MAXEXP10-1; 2264887Schin do 2274887Schin { if(f < _Sfpos10[v]) 2284887Schin v -= 1; 2294887Schin else 2304887Schin { 2314887Schin f *= _Sfneg10[v]; 2324887Schin if((n += (1<<v)) >= SF_IDIGITS) 2334887Schin return SF_INF; 2344887Schin } 235*8462SApril.Chin@Sun.COM } while(f >= (Sfdouble_t)CVT_LDBL_MAXINT); 236*8462SApril.Chin@Sun.COM } 237*8462SApril.Chin@Sun.COM else if(f > 0.0 && f < 0.1) 238*8462SApril.Chin@Sun.COM { /* scale to avoid excessive multiply by 10 below */ 239*8462SApril.Chin@Sun.COM v = SF_MAXEXP10-1; 240*8462SApril.Chin@Sun.COM do 241*8462SApril.Chin@Sun.COM { if(f <= _Sfneg10[v]) 242*8462SApril.Chin@Sun.COM { f *= _Sfpos10[v]; 243*8462SApril.Chin@Sun.COM if((n += (1<<v)) >= SF_IDIGITS) 244*8462SApril.Chin@Sun.COM return SF_INF; 245*8462SApril.Chin@Sun.COM } 246*8462SApril.Chin@Sun.COM else if (--v < 0) 247*8462SApril.Chin@Sun.COM break; 248*8462SApril.Chin@Sun.COM } while(f < 0.1); 249*8462SApril.Chin@Sun.COM n = -n; 2504887Schin } 2514887Schin *decpt = (int)n; 2524887Schin 2534887Schin b = sp = buf + SF_INTPART; 254*8462SApril.Chin@Sun.COM if((v = (CVT_LDBL_INT)f) != 0) 2554887Schin { /* translate the integer part */ 2564887Schin f -= (Sfdouble_t)v; 2574887Schin 258*8462SApril.Chin@Sun.COM sfucvt(v,sp,n,ep,CVT_LDBL_INT,unsigned CVT_LDBL_INT); 2594887Schin 2604887Schin n = b-sp; 2614887Schin if((*decpt += (int)n) >= SF_IDIGITS) 2624887Schin return SF_INF; 2634887Schin b = sp; 2644887Schin sp = buf + SF_INTPART; 2654887Schin } 2664887Schin else n = 0; 2674887Schin 2684887Schin /* remaining number of digits to compute; add 1 for later rounding */ 2694887Schin n = (((format&SFFMT_EFORMAT) || *decpt <= 0) ? 1 : *decpt+1) - n; 2704887Schin if(n_digit > 0) 2714887Schin { if(n_digit > LDBL_DIG) 2724887Schin n_digit = LDBL_DIG; 2734887Schin n += n_digit; 2744887Schin } 2754887Schin 2764887Schin if((ep = (sp+n)) > (endsp = buf+(size-2))) 2774887Schin ep = endsp; 2784887Schin if(sp > ep) 2794887Schin sp = ep; 2804887Schin else 2814887Schin { 2824887Schin if((format&SFFMT_EFORMAT) && *decpt == 0 && f > 0.) 2834887Schin { Sfdouble_t d; 2844887Schin while((long)(d = f*10.) == 0) 2854887Schin { f = d; 2864887Schin *decpt -= 1; 2874887Schin } 2884887Schin } 2894887Schin 2904887Schin while(sp < ep) 2914887Schin { /* generate fractional digits */ 2924887Schin if(f <= 0.) 2934887Schin { /* fill with 0's */ 2944887Schin do { *sp++ = '0'; } while(sp < ep); 2954887Schin goto done; 2964887Schin } 2974887Schin else if((n = (long)(f *= 10.)) < 10) 2984887Schin { *sp++ = '0' + n; 2994887Schin f -= n; 3004887Schin } 3014887Schin else /* n == 10 */ 3024887Schin { do { *sp++ = '9'; } while(sp < ep); 3034887Schin } 3044887Schin } 3054887Schin } 3064887Schin } else 3074887Schin #endif 308*8462SApril.Chin@Sun.COM { double f = *(double*)vp; 3094887Schin 310*8462SApril.Chin@Sun.COM if(isnan(f)) 311*8462SApril.Chin@Sun.COM { 312*8462SApril.Chin@Sun.COM #if _lib_signbit 313*8462SApril.Chin@Sun.COM if (signbit(f)) 314*8462SApril.Chin@Sun.COM #else 315*8462SApril.Chin@Sun.COM if (f < 0) 316*8462SApril.Chin@Sun.COM #endif 317*8462SApril.Chin@Sun.COM *sign = 1; 318*8462SApril.Chin@Sun.COM return SF_NAN; 319*8462SApril.Chin@Sun.COM } 3204887Schin #if _lib_isinf 3214887Schin if (n = isinf(f)) 322*8462SApril.Chin@Sun.COM { 323*8462SApril.Chin@Sun.COM #if _lib_signbit 324*8462SApril.Chin@Sun.COM if (signbit(f)) 325*8462SApril.Chin@Sun.COM #else 326*8462SApril.Chin@Sun.COM if (n < 0 || f < 0) 327*8462SApril.Chin@Sun.COM #endif 3284887Schin *sign = 1; 3294887Schin return SF_INF; 3304887Schin } 3314887Schin #endif 3324887Schin #if _c99_in_the_wild 333*8462SApril.Chin@Sun.COM # if _lib_signbit 3344887Schin if (signbit(f)) 335*8462SApril.Chin@Sun.COM # else 336*8462SApril.Chin@Sun.COM # if _lib_copysign 3374887Schin if (copysign(1.0, f) < 0.0) 338*8462SApril.Chin@Sun.COM # else 3394887Schin if (f < 0.0) 340*8462SApril.Chin@Sun.COM # endif 341*8462SApril.Chin@Sun.COM # endif 3424887Schin { f = -f; 3434887Schin *sign = 1; 3444887Schin } 345*8462SApril.Chin@Sun.COM # if _lib_fpclassify 3464887Schin switch (fpclassify(f)) 3474887Schin { 3484887Schin case FP_INFINITE: 3494887Schin return SF_INF; 3504887Schin case FP_NAN: 3514887Schin return SF_NAN; 3524887Schin case FP_ZERO: 3534887Schin return SF_ZERO; 3544887Schin } 355*8462SApril.Chin@Sun.COM # endif 3564887Schin #else 357*8462SApril.Chin@Sun.COM # if _lib_signbit 358*8462SApril.Chin@Sun.COM if (signbit(f)) 359*8462SApril.Chin@Sun.COM # else 360*8462SApril.Chin@Sun.COM if (f < 0.0 || f == 0.0 && neg0d(f)) 361*8462SApril.Chin@Sun.COM # endif 3624887Schin { f = -f; 3634887Schin *sign = 1; 3644887Schin } 3654887Schin #endif 3664887Schin if(f < DBL_MIN) 3674887Schin return SF_ZERO; 3684887Schin if(f > DBL_MAX) 3694887Schin return SF_INF; 3704887Schin 3714887Schin if(format & SFFMT_AFORMAT) 3724887Schin { double g; 3734887Schin int x; 3744887Schin b = sp = buf; 3754887Schin ep = (format & SFFMT_UPPER) ? ux : lx; 3764887Schin if(n_digit <= 0 || n_digit >= (size - 9)) 3774887Schin n_digit = size - 9; 3784887Schin endsp = sp + n_digit; 3794887Schin 3804887Schin g = frexp(f, &x); 3814887Schin *decpt = x; 3824887Schin f = ldexp(g, 8 * sizeof(m) - 3); 3834887Schin 3844887Schin for (;;) 3854887Schin { m = f; 3864887Schin x = 8 * sizeof(m); 3874887Schin while ((x -= 4) >= 0) 3884887Schin { *sp++ = ep[(m >> x) & 0xf]; 3894887Schin if (sp >= endsp) 3904887Schin { ep = sp + 1; 3914887Schin goto done; 3924887Schin } 3934887Schin } 3944887Schin f -= m; 3954887Schin f = ldexp(f, 8 * sizeof(m)); 3964887Schin } 3974887Schin } 3984887Schin n = 0; 399*8462SApril.Chin@Sun.COM if(f >= (double)CVT_DBL_MAXINT) 4004887Schin { /* scale to a small enough number to fit an int */ 4014887Schin v = SF_MAXEXP10-1; 4024887Schin do 4034887Schin { if(f < _Sfpos10[v]) 4044887Schin v -= 1; 4054887Schin else 4064887Schin { f *= _Sfneg10[v]; 4074887Schin if((n += (1<<v)) >= SF_IDIGITS) 4084887Schin return SF_INF; 4094887Schin } 410*8462SApril.Chin@Sun.COM } while(f >= (double)CVT_DBL_MAXINT); 411*8462SApril.Chin@Sun.COM } 412*8462SApril.Chin@Sun.COM else if(f > 0.0 && f < 1e-8) 413*8462SApril.Chin@Sun.COM { /* scale to avoid excessive multiply by 10 below */ 414*8462SApril.Chin@Sun.COM v = SF_MAXEXP10-1; 415*8462SApril.Chin@Sun.COM do 416*8462SApril.Chin@Sun.COM { if(f <= _Sfneg10[v]) 417*8462SApril.Chin@Sun.COM { f *= _Sfpos10[v]; 418*8462SApril.Chin@Sun.COM if((n += (1<<v)) >= SF_IDIGITS) 419*8462SApril.Chin@Sun.COM return SF_INF; 420*8462SApril.Chin@Sun.COM } 421*8462SApril.Chin@Sun.COM else if(--v < 0) 422*8462SApril.Chin@Sun.COM break; 423*8462SApril.Chin@Sun.COM } while(f < 0.1); 424*8462SApril.Chin@Sun.COM n = -n; 4254887Schin } 4264887Schin *decpt = (int)n; 4274887Schin 4284887Schin b = sp = buf + SF_INTPART; 429*8462SApril.Chin@Sun.COM if((v = (CVT_DBL_INT)f) != 0) 4304887Schin { /* translate the integer part */ 4314887Schin f -= (double)v; 4324887Schin 433*8462SApril.Chin@Sun.COM sfucvt(v,sp,n,ep,CVT_DBL_INT,unsigned CVT_DBL_INT); 4344887Schin 4354887Schin n = b-sp; 4364887Schin if((*decpt += (int)n) >= SF_IDIGITS) 4374887Schin return SF_INF; 4384887Schin b = sp; 4394887Schin sp = buf + SF_INTPART; 4404887Schin } 4414887Schin else n = 0; 4424887Schin 4434887Schin /* remaining number of digits to compute; add 1 for later rounding */ 4444887Schin n = (((format&SFFMT_EFORMAT) || *decpt <= 0) ? 1 : *decpt+1) - n; 4454887Schin if(n_digit > 0) 4464887Schin { if(n_digit > DBL_DIG) 4474887Schin n_digit = DBL_DIG; 4484887Schin n += n_digit; 4494887Schin } 4504887Schin 4514887Schin if((ep = (sp+n)) > (endsp = buf+(size-2))) 4524887Schin ep = endsp; 4534887Schin if(sp > ep) 4544887Schin sp = ep; 4554887Schin else 4564887Schin { 4574887Schin if((format&SFFMT_EFORMAT) && *decpt == 0 && f > 0.) 4584887Schin { reg double d; 4594887Schin while((long)(d = f*10.) == 0) 4604887Schin { f = d; 4614887Schin *decpt -= 1; 4624887Schin } 4634887Schin } 4644887Schin 4654887Schin while(sp < ep) 4664887Schin { /* generate fractional digits */ 4674887Schin if(f <= 0.) 4684887Schin { /* fill with 0's */ 4694887Schin do { *sp++ = '0'; } while(sp < ep); 4704887Schin goto done; 4714887Schin } 4724887Schin else if((n = (long)(f *= 10.)) < 10) 4734887Schin { *sp++ = (char)('0' + n); 4744887Schin f -= n; 4754887Schin } 4764887Schin else /* n == 10 */ 4774887Schin { do { *sp++ = '9'; } while(sp < ep); 478*8462SApril.Chin@Sun.COM break; 4794887Schin } 4804887Schin } 4814887Schin } 4824887Schin } 4834887Schin 4844887Schin if(ep <= b) 4854887Schin ep = b+1; 4864887Schin else if(ep < endsp) 4874887Schin { /* round the last digit */ 4884887Schin *--sp += 5; 4894887Schin while(*sp > '9') 4904887Schin { *sp = '0'; 4914887Schin if(sp > b) 4924887Schin *--sp += 1; 4934887Schin else 4944887Schin { /* next power of 10 */ 4954887Schin *sp = '1'; 4964887Schin *decpt += 1; 4974887Schin if(!(format&SFFMT_EFORMAT)) 4984887Schin { /* add one more 0 for %f precision */ 4994887Schin ep[-1] = '0'; 5004887Schin ep += 1; 5014887Schin } 5024887Schin } 5034887Schin } 5044887Schin } 5054887Schin 5064887Schin done: 5074887Schin *--ep = '\0'; 5084887Schin if(len) 5094887Schin *len = ep-b; 5104887Schin return b; 5114887Schin } 512