괄호 () 를 이용한 우선순위 변경과 몇가지 수학함수 (abs, acos, asin, atan, ceil, cos, cosh, exp, floor, ln, log, pi, sin, sinh, sqr, tan, tanh) 를 사용할 수 있다.

CalcLib.cpp
#include <math.h>
#include <string.h>
#define _PI_ 3.14159265359
enum CALCCLASS_TYPE {ADD, SUB, MUL, DEV, OPEN, CLOSE, NUM, STRING, EXP, END, _ERROR_};
class Ccalcclass {
public:
// if (_DegRad_) degree else radian.
double calc (char *s, int _DegRad_);
private:
void lex ();
double A ();
double B ();
double C ();
double D ();
double E ();
double S ();
char *data;
int p;
int type;
double num;
char str[10];
int DegRad;
};
void Ccalcclass::lex () {
double point;
int i;
while (data[p] == ' ') p++;
if (data[p] == '+') type = ADD;
else
if (data[p] == '-') type = SUB;
else
if (data[p] == '*') type = MUL;
else
if (data[p] == '/') type = DEV;
else
if (data[p] == '(') type = OPEN;
else
if (data[p] == ')') type = CLOSE;
else
if (data[p] == '^') type = EXP;
else
if ((('0' <= data[p]) && (data[p] <= '9')) || (data[p] == '.')) {
type = NUM;
num = 0;
point = 0.0;
while ((('0' <= data[p]) && (data[p] <= '9')) || (data[p] == '.')) {
if (data[p] != '.') {
if (point == 0.0) num = num*10 + (data[p] - '0');
else {
num = num + point * (data[p] - '0');
point = point * 0.1;
}
} else
if (point == 0) point = 0.1;
else {
type = _ERROR_;
return;
}
p++;
}
return;
} else
if (('a' <= data[p]) && (data[p] <= 'z')) {
type = STRING;
i = 0;
while (('a' <= data[p]) && (data[p] <= 'z') && i<9) {
str[i++] = data[p++];
}
str[i] = 0;
return;
} else
if (data[p] == 0) type = END;
else
type = _ERROR_;
p++;
}
double Ccalcclass::A () {
double rv;
rv = B ();
while ((type == ADD) || (type == SUB)) {
if (type == ADD) {
lex ();
rv = rv + B ();
} else
if (type == SUB) {
lex ();
rv = rv - B ();
}
}
return rv;
}
double Ccalcclass::B () {
double rv;
rv = C ();
while ((type == MUL) || (type == DEV)) {
if (type == MUL) {
lex ();
rv = rv * C ();
} else
if (type == DEV) {
lex ();
rv = rv / C ();
}
}
return rv;
}
double Ccalcclass::C () {
double rv;
if (type == SUB) {
lex ();
rv = 0.0 - D ();
} else
rv = D ();
return rv;
}
double Ccalcclass::D () {
double rv;
rv = E ();
while (type == EXP) {
lex ();
rv = pow (rv, E());
}
return rv;
}
double Ccalcclass::E () {
double rv;
if (type == OPEN) {
lex ();
rv = A ();
if (type == CLOSE) lex ();
else type = _ERROR_;
} else
if (type == NUM) {
rv = num;
lex ();
} else
if (type == STRING) rv = S ();
else
type = _ERROR_;
return rv;
}
double Ccalcclass::S () {
double rv;
if (stricmp (str, "abs") == 0) {
lex ();
rv = fabs (C ());
} else
if (stricmp (str, "acos") == 0) {
lex ();
if (DegRad) rv = acos (C ())/_PI_*180;
else rv = acos (C ());
} else
if (stricmp (str, "asin") == 0) {
lex ();
if (DegRad) rv = asin (C ())/_PI_*180;
else rv = asin (C ());
} else
if (stricmp (str, "atan") == 0) {
lex ();
if (DegRad) rv = atan (C ())/_PI_*180;
else rv = atan (C ());
} else
if (stricmp (str, "ceil") == 0) {
lex ();
rv = ceil (C ());
} else
if (stricmp (str, "cos") == 0) {
lex ();
if (DegRad) rv = cos (C ()*_PI_/180);
else rv = cos (C ());
} else
if (stricmp (str, "cosh") == 0) {
lex ();
rv = cosh (C ());
} else
if (stricmp (str, "exp") == 0) {
lex ();
rv = exp (C ());
} else
if (stricmp (str, "floor") == 0) {
lex ();
rv = floor (C ());
} else
if (stricmp (str, "ln") == 0) {
lex ();
rv = log (C ());
} else
if (stricmp (str, "log") == 0) {
lex ();
rv = log10 (C ());
} else
if (stricmp (str, "pi") == 0) {
lex ();
rv = _PI_;
} else
if (stricmp (str, "sin") == 0) {
lex ();
if (DegRad) rv = sin (C ()*_PI_/180);
else rv = sin (C ());
} else
if (stricmp (str, "sinh") == 0) {
lex ();
rv = sinh (C ());
} else
if (stricmp (str, "sqr") == 0) {
lex ();
rv = sqrt (C ());
} else
if (stricmp (str, "tan") == 0) {
lex ();
if (DegRad) rv = tan (C ()*_PI_/180);
else rv = tan (C ());
} else
if (stricmp (str, "tanh") == 0) {
lex ();
rv = tanh (C ());
} else
type = _ERROR_;
return rv;
}
double Ccalcclass::calc (char *s, int _DegRad_) {
double rv;
data = s;
DegRad = _DegRad_;
p = 0;
lex ();
rv = A ();
if (type != END) s[0] = 0;
return rv;
}
double calc (char *s, int DegRad) {
static Ccalcclass calcclass;
return calcclass.calc (s, DegRad);
}