#include "sfhdr.h"
static char *Inf = "Inf", *Zero = "0";
#define SF_INTPART (SF_IDIGITS/2)
#define SF_INFINITE ((_Sfi = 3), Inf)
#define SF_ZERO ((_Sfi = 1), Zero)
#if __STD_C
char* _sfcvt(Void_t* dv, int n_digit, int* decpt, int* sign, int format)
#else
char* _sfcvt(dv,n_digit,decpt,sign,format)
Void_t* dv;
int n_digit;
int* decpt;
int* sign;
int format;
#endif
{
reg char *sp;
reg long n, v;
reg char *ep, *buf, *endsp;
static char *Buf;
if(!Buf && !(Buf = (char*)malloc(SF_MAXDIGITS)))
return SF_INFINITE;
*sign = *decpt = 0;
#if !_ast_fltmax_double
if(format&SFFMT_LDOUBLE)
{ Sfdouble_t dval = *((Sfdouble_t*)dv);
if(dval == 0.)
return SF_ZERO;
else if((*sign = (dval < 0.)) )
dval = -dval;
n = 0;
if(dval >= (Sfdouble_t)SF_MAXLONG)
{
v = SF_MAXEXP10-1;
do
{ if(dval < _Sfpos10[v])
v -= 1;
else
{
dval *= _Sfneg10[v];
if((n += (1<<v)) >= SF_IDIGITS)
return SF_INFINITE;
}
} while(dval >= (Sfdouble_t)SF_MAXLONG);
}
*decpt = (int)n;
buf = sp = Buf + SF_INTPART;
if((v = (int)dval) != 0)
{
dval -= (Sfdouble_t)v;
sfucvt(v,sp,n,ep,long,ulong);
n = buf-sp;
if((*decpt += (int)n) >= SF_IDIGITS)
return SF_INFINITE;
buf = sp;
sp = Buf + SF_INTPART;
}
else n = 0;
n = (((format&SFFMT_EFORMAT) || *decpt <= 0) ? 1 : *decpt+1) - n;
if(n_digit > 0)
n += n_digit;
if((ep = (sp+n)) > (endsp = Buf+(SF_MAXDIGITS-2)))
ep = endsp;
if(sp > ep)
sp = ep;
else
{
if((format&SFFMT_EFORMAT) && *decpt == 0 && dval > 0.)
{ Sfdouble_t d;
while((int)(d = dval*10.) == 0)
{ dval = d;
*decpt -= 1;
}
}
while(sp < ep)
{
if(dval <= 0.)
{
do { *sp++ = '0'; } while(sp < ep);
goto done;
}
else if((n = (long)(dval *= 10.)) < 10)
{ *sp++ = '0' + n;
dval -= n;
}
else
{ do { *sp++ = '9'; } while(sp < ep);
}
}
}
} else
#endif
{ double dval = *((double*)dv);
if(dval == 0.)
return SF_ZERO;
else if((*sign = (dval < 0.)) )
dval = -dval;
n = 0;
if(dval >= (double)SF_MAXLONG)
{
v = SF_MAXEXP10-1;
do
{ if(dval < _Sfpos10[v])
v -= 1;
else
{ dval *= _Sfneg10[v];
if((n += (1<<v)) >= SF_IDIGITS)
return SF_INFINITE;
}
} while(dval >= (double)SF_MAXLONG);
}
*decpt = (int)n;
buf = sp = Buf + SF_INTPART;
if((v = (int)dval) != 0)
{
dval -= (double)v;
sfucvt(v,sp,n,ep,long,ulong);
n = buf-sp;
if((*decpt += (int)n) >= SF_IDIGITS)
return SF_INFINITE;
buf = sp;
sp = Buf + SF_INTPART;
}
else n = 0;
n = (((format&SFFMT_EFORMAT) || *decpt <= 0) ? 1 : *decpt+1) - n;
if(n_digit > 0)
n += n_digit;
if((ep = (sp+n)) > (endsp = Buf+(SF_MAXDIGITS-2)))
ep = endsp;
if(sp > ep)
sp = ep;
else
{
if((format&SFFMT_EFORMAT) && *decpt == 0 && dval > 0.)
{ reg double d;
while((int)(d = dval*10.) == 0)
{ dval = d;
*decpt -= 1;
}
}
while(sp < ep)
{
if(dval <= 0.)
{
do { *sp++ = '0'; } while(sp < ep);
goto done;
}
else if((n = (int)(dval *= 10.)) < 10)
{ *sp++ = (char)('0' + n);
dval -= n;
}
else
{ do { *sp++ = '9'; } while(sp < ep);
}
}
}
}
if(ep <= buf)
ep = buf+1;
else if(ep < endsp)
{
*--sp += 5;
while(*sp > '9')
{ *sp = '0';
if(sp > buf)
*--sp += 1;
else
{
*sp = '1';
*decpt += 1;
if(!(format&SFFMT_EFORMAT))
{
ep[-1] = '0';
ep += 1;
}
}
}
}
done:
*--ep = '\0';
_Sfi = ep-buf;
return buf;
}