ultimatepp/uppdev/MySupport/Core.cpp
cxl 351994a6cc Adding uppdev....
git-svn-id: svn://ultimatepp.org/upp/trunk@328 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-08-15 08:36:24 +00:00

209 lines
4.7 KiB
C++

#include "support.h"
double MyScanDouble(const char *p, const char **endptr)
{
const char *begin = p;
while(*p && (byte)*p <= ' ')
p++;
bool neg = false;
if(*p == '+' || *p == '-')
neg = (*p++ == '-');
if((byte)(*p - '0') >= 10 && !(*p == *GetSystemDecimalSeparator() && (byte)(p[1] - '0') < 10))
{
if(endptr) *endptr = begin;
return Null;
}
double mantissa = 0;
char c;
int exp = 0;
while((byte)(*p - '0') < 10)
if((c = *p++) != '0')
{
if(exp) { mantissa *= ipow10(exp); exp = 0; }
mantissa = 10 * mantissa + c - '0';
}
else
exp++;
int raise = exp;
if(*p == *GetSystemDecimalSeparator()) // decimal part
while((byte)((c = *++p) - '0') < 10)
if(c != '0')
{
if(raise) { mantissa *= ipow10(raise); exp -= raise; raise = 0; }
exp--;
mantissa = 10 * mantissa + c - '0';
}
else
raise++;
if(*p == 'E' || *p == 'e')
{ // exponent
int vexp = ScanInt(p + 1, endptr);
if(!IsNull(vexp))
exp += vexp;
}
else
if(endptr) *endptr = p;
if(exp)
{
double e = ipow10(tabs(exp));
mantissa = (exp > 0 ? mantissa * e : mantissa / e);
}
return neg ? -mantissa : mantissa;
}
double MyScanDouble(const wchar *p, const wchar **endptr)
{
const wchar *begin = p;
while(*p && *p <= ' ')
p++;
bool neg = false;
if(*p == '+' || *p == '-')
neg = (*p++ == '-');
if((unsigned)(*p - '0') >= 10)
{
if(endptr) *endptr = begin;
return Null;
}
double mantissa = 0;
wchar c;
int exp = 0;
while((unsigned)(*p - '0') < 10)
if((c = *p++) != '0')
{
if(exp) { mantissa *= ipow10(exp); exp = 0; }
mantissa = 10 * mantissa + c - '0';
}
else
exp++;
int raise = exp;
if(*p == *GetSystemDecimalSeparator()) // decimal part
while((unsigned)((c = *++p) - '0') < 10)
if(c != '0')
{
if(raise) { mantissa *= ipow10(raise); exp -= raise; raise = 0; }
exp--;
mantissa = 10 * mantissa + c - '0';
}
else
raise++;
if(*p == 'E' || *p == 'e')
{ // exponent
int vexp = ScanInt(p + 1, endptr);
if(!IsNull(vexp))
exp += vexp;
}
else
if(endptr) *endptr = p;
if(exp)
{
double e = ipow10(tabs(exp));
mantissa = (exp > 0 ? mantissa * e : mantissa / e);
}
return neg ? -mantissa : mantissa;
}
String MyFormatDouble(double d, int digits, int flags, int pad_exp)
{
if(IsNull(d))
return Null;
double ad = fabs(d);
bool is_exp = (flags & FD_EXP);
if(!(flags & FD_FIX))
{
is_exp = ad && (ad <= 1e-15 || ad >= 1e15);
if(flags & FD_REL)
{
double bd = ipow10(2 * digits);
if(ad && (ad * bd <= 1 || ad >= bd))
is_exp = true;
}
}
if(is_exp)
return MyFormatDoubleExp(d, digits, flags, pad_exp);
else
return MyFormatDoubleFix(d, digits, flags);
}
String MyFormatDoubleFix(double d, int digits, int flags)
{
if(IsNull(d))
return Null;
int exp;
String dig = FormatDoubleDigits(d, digits, flags, exp);
if(flags & FD_REL)
digits = max(0, digits - Nvl(exp, 0) - 1);
String out;
if(flags & FD_SIGN || d < 0 && !IsNull(exp))
out.Cat(d >= 0 ? '+' : '-');
if(IsNull(exp) || exp < -digits)
{
out.Cat('0');
if(flags & FD_ZERO)
{
out.Cat(*GetSystemDecimalSeparator());
out.Cat('0', digits);
}
}
else if(exp < 0)
{
out.Cat("0");
out.Cat(*GetSystemDecimalSeparator());
out.Cat('0', -1 - exp);
int fill = digits + exp + 1;
if(!(flags & FD_ZERO) || dig.GetLength() >= fill)
out.Cat(dig, min(fill, dig.GetLength()));
else
{
out.Cat(dig);
out.Cat('0', fill - dig.GetLength());
}
}
else if(exp < dig.GetLength())
{
out.Cat(dig, ++exp);
if(digits > 0 && ((flags & FD_ZERO) || dig.GetLength() > exp))
{
out.Cat(*GetSystemDecimalSeparator());
if(!(flags & FD_ZERO) || dig.GetLength() - exp >= digits)
out.Cat(dig.Begin() + exp, min(dig.GetLength() - exp, digits));
else
{
out.Cat(dig.Begin() + exp, dig.GetLength() - exp);
out.Cat('0', digits - (dig.GetLength() - exp));
}
}
}
else
{
out.Cat(dig);
out.Cat('0', exp - dig.GetLength() + 1);
if(digits > 0 && (flags & FD_ZERO))
{
out.Cat(*GetSystemDecimalSeparator());
out.Cat('0', digits);
}
}
return out;
}
String MyFormatDoubleExp(double d, int digits, int flags, int fill_exp)
{
if(IsNull(d))
return Null;
int exp;
String dig = FormatDoubleDigits(d, digits, flags | FD_REL, exp);
exp = Nvl(exp, 0);
String out;
if(flags & FD_SIGN || d < 0 && !IsNull(exp))
out.Cat(d >= 0 ? '+' : '-');
out.Cat(dig[0]);
if(dig.GetLength() > 1)
{
out.Cat(*GetSystemDecimalSeparator());
out.Cat(dig.Begin() + 1, dig.GetLength() - 1);
}
out.Cat(flags & FD_CAP_E ? 'E' : 'e');
out.Cat(FormatIntDec(exp, fill_exp, '0', flags & FD_SIGN_EXP));
return out;
}