2003-09-15 23:20:36 +00:00
|
|
|
#include <windows.h>
|
|
|
|
#include "MyMath.h"
|
|
|
|
#include "Math.h"
|
|
|
|
|
|
|
|
// Converts String to Int (Dec, Hex) or Float value
|
|
|
|
void StringToItem(char *&s, ExpressionItem *item, int options)
|
|
|
|
{
|
|
|
|
item->type = IT_CONST | ITC_INT;
|
|
|
|
__int64 &v=*((__int64*)&(item->param1));
|
|
|
|
v = 0;
|
|
|
|
|
|
|
|
// Check for right input
|
|
|
|
if (!s) return;
|
|
|
|
|
|
|
|
// String-value
|
2005-11-24 19:38:32 +00:00
|
|
|
if ((((options & (STI_FLOAT | STI_INT)) == 0) || *s == '\'' || *s == '\"' || *s == '`' ||
|
2003-09-15 23:20:36 +00:00
|
|
|
((*s != '+') && (*s != '-') && ((*s < '0') || (*s > '9'))))
|
|
|
|
&& (options & STI_STRING))
|
|
|
|
{
|
|
|
|
// end of string char
|
|
|
|
char eol = 0;
|
|
|
|
if (*s == '\'' || *s == '\"' || *s == '`') eol = *s;
|
|
|
|
else s--;
|
|
|
|
|
|
|
|
item->type = IT_CONST | ITC_STRING;
|
|
|
|
// allocate memory buffer for string
|
|
|
|
char *sp;
|
|
|
|
sp = *((char**)&(item->param1)) = AllocString();
|
|
|
|
while (*(++s) && (*s != eol))
|
|
|
|
{
|
|
|
|
*(sp++) = *s;
|
|
|
|
}
|
|
|
|
if (*s == eol) s++;
|
|
|
|
*sp = 0;
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
// strip leading spaces and tabs
|
|
|
|
while ((*s == ' ') || (*s == '\t')) s++;
|
|
|
|
// Hex-value
|
|
|
|
if ((options & STI_INT) && *s == '0' && (s[1] == 'x' || s[1] == 'X'))
|
|
|
|
{
|
|
|
|
s++;
|
|
|
|
while (*(s+1) == '0') *s++;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
int c=*(++s);
|
|
|
|
if (c >= '0' && c <= '9') c-='0';
|
|
|
|
else if (c >= 'a' && c <= 'f') c-='a'-10;
|
|
|
|
else if (c >= 'A' && c <= 'F') c-='A'-10;
|
|
|
|
else break;
|
|
|
|
v<<=4;
|
|
|
|
v+=c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Dec-value, possible floating-point
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int sign=0, numsignif = 0;
|
|
|
|
if (*s == '-') sign++; else s--;
|
|
|
|
while (*(s+1) == '0') *s++;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
int c=*(++s) - '0'; numsignif++;
|
2005-11-24 19:38:32 +00:00
|
|
|
if ((options & STI_FLOAT) &&
|
2003-09-15 23:20:36 +00:00
|
|
|
((c == ('e'-'0')) || (c==('E'-'0')) || (c==('.'-'0'))
|
|
|
|
|| (numsignif > 18)))
|
|
|
|
{
|
|
|
|
// Switch to floating point conversion rountine
|
|
|
|
item->type = IT_CONST | ITC_FLOAT;
|
|
|
|
double& d = *((double*)&(item->param1));
|
|
|
|
d = (double) v;
|
|
|
|
|
|
|
|
while ((c >= 0) && (c <= 9))
|
|
|
|
{
|
|
|
|
d = d*10.0 + (double) c;
|
|
|
|
c=*(++s) - '0';
|
|
|
|
}
|
|
|
|
|
|
|
|
// sub-decimal part
|
|
|
|
if (c == ('.'-'0'))
|
|
|
|
{
|
|
|
|
double pwr = 1.0, dec = 0.0;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
c=*(++s) - '0';
|
|
|
|
if ((c < 0) || (c > 9)) break;
|
|
|
|
dec = dec*10.0 + (double) c;
|
|
|
|
pwr *= 10.0;
|
|
|
|
}
|
|
|
|
d += dec/pwr;
|
|
|
|
}
|
|
|
|
// exponental part
|
|
|
|
if ((c == ('E'-'0')) || (c == ('e'-'0')))
|
|
|
|
{
|
|
|
|
int expc = 0, esign = 0;
|
|
|
|
s++;
|
|
|
|
// detect exponential sign
|
2005-11-24 19:38:32 +00:00
|
|
|
if ((*s == '+') || (*s == '-'))
|
2003-09-15 23:20:36 +00:00
|
|
|
esign = (*s == '-');
|
|
|
|
else s--;
|
|
|
|
|
|
|
|
// detect exp value
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
c=*(++s) - '0';
|
|
|
|
if ((c < 0) || (c > 9)) break;
|
|
|
|
expc = expc*10 + c;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (expc >= DBL_MAX_EXP)
|
|
|
|
{
|
|
|
|
d = HUGE_VAL;
|
|
|
|
expc = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
double pwr = 1;
|
|
|
|
while (expc > 99) { pwr *= 1.0e100; expc -= 100; }
|
|
|
|
while (expc > 9) { pwr *= 1.0e10; expc -= 10; }
|
|
|
|
while (expc) { pwr *= 10.0; expc--; }
|
|
|
|
if (esign) d /= pwr;
|
|
|
|
else d *= pwr;
|
|
|
|
}
|
|
|
|
if (sign) d = -d;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (c < 0 || c > 9) break;
|
|
|
|
v*=10;
|
|
|
|
v+=c;
|
|
|
|
}
|
|
|
|
if (sign) v = -v;
|
|
|
|
if ((options & STI_FLOAT) && ((options & STI_INT) == 0))
|
|
|
|
{
|
|
|
|
double& d = *((double*)&(item->param1));
|
2005-11-24 19:38:32 +00:00
|
|
|
d = (double) v;
|
2003-09-15 23:20:36 +00:00
|
|
|
item->type = IT_CONST | ITC_FLOAT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemToString(char *sbuf, ExpressionItem *item)
|
|
|
|
{
|
|
|
|
if ((item == NULL) || ((item->type & ITEMTYPE) != IT_CONST))
|
|
|
|
{
|
|
|
|
*sbuf = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-11-24 19:38:32 +00:00
|
|
|
switch (item->type & ITEMSUBTYPE)
|
2003-09-15 23:20:36 +00:00
|
|
|
{
|
|
|
|
case ITC_STRING:
|
|
|
|
{
|
|
|
|
char *ptr = *((char**)&(item->param1));
|
|
|
|
while (*(sbuf++) = *(ptr++));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ITC_ARRAY:
|
2005-11-24 19:38:32 +00:00
|
|
|
{
|
2003-09-15 23:20:36 +00:00
|
|
|
ArrayDesc *ad = (ArrayDesc *) item->param1;
|
|
|
|
for (int index = 0; index < ad->count; index++)
|
2005-11-24 19:38:32 +00:00
|
|
|
if ((ad->array[index]) &&
|
2003-09-15 23:20:36 +00:00
|
|
|
((ad->array[index]->type & (ITEMTYPE|ITEMSUBTYPE)) == (IT_CONST | ITC_INT)))
|
|
|
|
if ((*(sbuf++) = (char) *((__int64*)&(ad->array[index]->param1))) == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ITC_FLOAT:
|
|
|
|
FloatFormat(sbuf, *((double*)&(item->param1)), 6);
|
|
|
|
break;
|
|
|
|
case ITC_INT:
|
|
|
|
itoa64(*((__int64*)&(item->param1)), sbuf);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void itoa64(__int64 i, char *buffer)
|
|
|
|
{
|
|
|
|
char buf[128], *b = buf;
|
|
|
|
|
|
|
|
if (i < 0)
|
|
|
|
{
|
|
|
|
*(buffer++) = '-';
|
|
|
|
i = -i;
|
|
|
|
}
|
|
|
|
if (i == 0) *(buffer++) = '0';
|
2005-11-24 19:38:32 +00:00
|
|
|
else
|
2003-09-15 23:20:36 +00:00
|
|
|
{
|
2005-11-24 19:38:32 +00:00
|
|
|
while (i > 0)
|
2003-09-15 23:20:36 +00:00
|
|
|
{
|
|
|
|
*(b++) = '0' + ((char) (i%10));
|
|
|
|
i /= 10;
|
|
|
|
}
|
|
|
|
while (b > buf) *(buffer++) = *(--b);
|
|
|
|
}
|
|
|
|
*buffer = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define _FLOAT_ROUND_ADJUST (double)5e-15
|
|
|
|
extern "C"
|
|
|
|
int _ftol(double num);
|
|
|
|
|
2007-02-23 15:10:42 +00:00
|
|
|
int _floatp10(double *fnum, int *fsign, int prec)
|
|
|
|
{
|
|
|
|
int fpower, _d;
|
|
|
|
fcvt(*fnum, prec, &fpower, &_d);
|
|
|
|
|
|
|
|
if (*fnum < 0)
|
|
|
|
*fsign = -1;
|
|
|
|
else
|
|
|
|
*fsign = 1;
|
|
|
|
|
|
|
|
return fpower;
|
|
|
|
}
|
|
|
|
|
2003-09-15 23:20:36 +00:00
|
|
|
#define POS_INFINITY "#INF"
|
|
|
|
#define NEG_INFINITY "-#INF"
|
|
|
|
|
|
|
|
void FloatFormatF(char *s, double value, int prec)
|
|
|
|
{
|
|
|
|
int fpower, fsign, fdigit, fprec = 0, fzfill = 0;
|
|
|
|
|
|
|
|
fpower = _floatp10(&value, &fsign, prec);
|
|
|
|
if(fsign < 0) *s++ = '-';
|
|
|
|
if(fpower < 0)
|
|
|
|
{
|
|
|
|
*s++ = '0';
|
|
|
|
fpower++;
|
|
|
|
fzfill++;
|
|
|
|
} else {
|
|
|
|
while(fpower >= 0)
|
|
|
|
{
|
|
|
|
if(fprec < 16)
|
|
|
|
{
|
|
|
|
fdigit = (int)value;
|
|
|
|
*s++ = (char)((char)fdigit + (char)48);
|
|
|
|
value -= (double)fdigit;
|
|
|
|
value *= (double)10;
|
|
|
|
value += _FLOAT_ROUND_ADJUST;
|
|
|
|
fprec++;
|
|
|
|
} else {
|
|
|
|
*s++ = '0';
|
|
|
|
}
|
|
|
|
fpower--;
|
|
|
|
}
|
|
|
|
fpower = 0;
|
|
|
|
}
|
|
|
|
if(prec)
|
|
|
|
{
|
|
|
|
*s++ = '.';
|
|
|
|
while(prec)
|
|
|
|
{
|
|
|
|
if(fzfill && fpower < 0)
|
|
|
|
{
|
|
|
|
*s++ = '0';
|
|
|
|
fpower++;
|
|
|
|
} else {
|
|
|
|
if(fprec < 16)
|
|
|
|
{
|
|
|
|
fdigit = (int)value;
|
|
|
|
*s++ = (unsigned char)((unsigned char)fdigit +
|
|
|
|
(unsigned char)48);
|
|
|
|
|
|
|
|
value -= (double)fdigit;
|
|
|
|
value *= (double)10;
|
|
|
|
value += _FLOAT_ROUND_ADJUST;
|
|
|
|
fprec++;
|
|
|
|
} else {
|
|
|
|
*s++ = '0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
prec--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*s = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
void FloatFormatE(char *s, double fnum, int options)
|
|
|
|
{
|
|
|
|
int fpower, fsign, fdigit, fprec = 0, prec, fzfill = 0;
|
|
|
|
double sfnum;
|
|
|
|
|
|
|
|
prec = options & 0xF;
|
|
|
|
|
|
|
|
sfnum = fnum;
|
|
|
|
fpower = _floatp10(&sfnum, &fsign, -999);
|
|
|
|
fpower = _floatp10(&fnum, &fsign, prec - fpower);
|
|
|
|
if(fsign < 0) *s++ = '-';
|
|
|
|
fdigit = (int)fnum;
|
|
|
|
*s++ = (char)((char)fdigit + (char)48);
|
|
|
|
fnum -= (double)fdigit;
|
|
|
|
fnum *= (double)10;
|
|
|
|
fnum += _FLOAT_ROUND_ADJUST;
|
|
|
|
if(prec)
|
|
|
|
{
|
|
|
|
*s++ = '.';
|
|
|
|
while(prec)
|
|
|
|
{
|
|
|
|
if(fprec < 16)
|
|
|
|
{
|
|
|
|
fdigit = (int)fnum;
|
|
|
|
*s++ = (unsigned char)((unsigned char)fdigit +
|
|
|
|
(unsigned char)48);
|
|
|
|
fnum -= (double)fdigit;
|
|
|
|
fnum *= (double)10;
|
|
|
|
fnum += _FLOAT_ROUND_ADJUST;
|
|
|
|
fprec++;
|
|
|
|
} else *s++ = '0';
|
|
|
|
prec--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*s++ = ((options & FF_LEXP)?('E'):('e'));
|
|
|
|
if(fpower >= 0)
|
|
|
|
{
|
|
|
|
*s++ = '+';
|
|
|
|
} else {
|
|
|
|
*s++ = '-';
|
|
|
|
fpower = -fpower;
|
|
|
|
}
|
|
|
|
if(fpower < 10) *s++ = '0';
|
|
|
|
itoa64(fpower, s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FloatFormat(char *s, double value, int options)
|
|
|
|
{
|
|
|
|
int prec = options & 0xF;
|
|
|
|
|
2007-02-23 15:10:42 +00:00
|
|
|
*s = 0;
|
|
|
|
|
2003-09-15 23:20:36 +00:00
|
|
|
if(value == HUGE_VAL)
|
|
|
|
{
|
|
|
|
lstrcpy(s, POS_INFINITY);
|
|
|
|
return;
|
|
|
|
} else if(value == -HUGE_VAL) {
|
|
|
|
lstrcpy(s, NEG_INFINITY);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-02-23 15:10:42 +00:00
|
|
|
int decpt, sign;
|
|
|
|
|
|
|
|
char *res = fcvt(value, prec, &decpt, &sign);
|
|
|
|
|
|
|
|
if (res)
|
|
|
|
{
|
|
|
|
lstrcpyn(s, res, decpt + 1);
|
|
|
|
lstrcat(s, ".");
|
|
|
|
lstrcpy(s + decpt + 1, res + decpt);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*if (options & FF_NOEXP) FloatFormatF(s, value, prec);
|
2003-09-15 23:20:36 +00:00
|
|
|
else
|
|
|
|
if (options & FF_EXP) FloatFormatE(s, value, options);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double sfnum = value;
|
|
|
|
int fsign, fpower;
|
|
|
|
fpower = _floatp10(&sfnum, &fsign, -999);
|
|
|
|
sfnum = value;
|
|
|
|
fpower = _floatp10(&sfnum, &fsign, prec - fpower);
|
|
|
|
|
|
|
|
if((value != 0.0) && ((fpower < -4) || (fpower >= prec)))
|
|
|
|
FloatFormatE(s, value, options);
|
2005-11-24 19:38:32 +00:00
|
|
|
else
|
2003-09-15 23:20:36 +00:00
|
|
|
{
|
|
|
|
prec -= (fpower + 1);
|
|
|
|
if(prec <= 0) prec = 1;
|
|
|
|
FloatFormatF(s, value, prec);
|
2005-11-24 19:38:32 +00:00
|
|
|
}
|
2007-02-23 15:10:42 +00:00
|
|
|
}*/
|
2003-09-15 23:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int lstrcmpn(char *s1, const char *s2, int chars)
|
|
|
|
{
|
|
|
|
while ((chars > 0) && (*s1) && (*s2) && (*(s1) == *(s2))) chars--, s1++, s2++;
|
|
|
|
if ((chars == 0) || (*s1 == *s2)) return 0;
|
|
|
|
return (*s1 - *s2);
|
|
|
|
}
|