#include <iostream>
#include <cctype>
#include <cstdlib>
double _calc(const char* s, const char** p, bool& e);
double calculate(char* s, bool& e);
int main(void){
char s[] = "-(4)*10-(8+(7*(6/(5*(-4/(3/(2/(1/(((-8-(-2)*9)))-1)/2)/3)/4)/5))))+"\
"((10+20)/(-10+20-10+2*2+1)-1) + 500 * (1 / 123456789)";
bool err;
double res = calculate(s, err);
if(err)
std::cout << res << std::endl;
else
std::cout << "error calculate!" << std::endl;
return 0;
}
//вычисление мат-выражений из строки
double calculate(char* s, bool& e){
int i;
char* a, *b;
const char* p = NULL;
double n = 0.0;
for(i = 0, p = s; *p; ++p){
if(*p == '(')
++i;
else if(*p == ')'){
if(--i < 0)
break;
}
}
e = true;
if(*s && !i){
a = s;
while(*a && !isspace(*a))
++a;
for(b = a; *a; *a = *(++b)){
if(! isspace(*b))
++a;
}
if(*s)
n = _calc(s, &p, e);
else
e = false;
} else
e = false;
return n;
}
// рекурсивное вычисление мат-выражений из строки
double _calc(const char* s, const char** p, bool& e){
int neg;
char c, c1;
char* i;
const char* o;
double k, v, n = 0.0;
if((*s == '(') || (*s == '-' && *(s + 1) == '(')){
neg = (*s == '-');
n = _calc(s + (1 + neg), &o, e);
if(! e)
return 0.0;
s = o;
if(neg)
n = 0.0 - n;
} else {
n = strtod(s, &i);
if(s == i){
e = false;
return 0.0;
}
s = i;
}
while(*s && (*s != ')')){
c = *s++;
if(! *s){
e = false;
return 0.0;
}
if(*s == '('){
k = _calc(s + 1, &o, e);
if(! e)
return 0.0;
s = o;
} else {
k = strtod(s, &i);
if(s == i){
e = false;
return 0.0;
}
s = i;
}
switch(c){
case '*':
n *= k;
break;
case '/':
if(k == 0.0){
e = false;
return 0.0;
}
n /= k;
break;
case '+':
case '-':
if((*s == '*') || (*s == '/')) {
v = k;
while(*s && (*s != ')')) {
c1 = *s;
if((c1 == '+') || (c1 == '-'))
break;
++s;
if(*s == '('){
k = _calc(s + 1, &o, e);
if(! e)
return 0.0;
s = o;
} else {
k = strtod(s, &i);
if(s == i){
e = false;
return 0.0;
}
s = i;
}
if(c1 == '/') {
if(k == 0.0){
e = false;
return 0.0;
}
v /= k;
} else if(c1 == '*')
v *= k;
}
k = v;
}
if(c == '+')
n += k;
else if(c == '-')
n -= k;
if(*s == ')'){
*p = s + 1;
return n;
}
break;
}
}
if(*s == ')')
*p = s + 1;
return n;
}