home *** CD-ROM | disk | FTP | other *** search
- {
- >Does anyone have any source for evaluating math expressions? I would like to
- >find some source that can evaluate an expression like
- >
- > 5 * (3 + 4) or B * 3 + C
- }
-
- Program Test;
-
- Uses
- Strings; {You have to use your own unit}
-
- Var
- x : Real;
- maxvar : Integer;
- s : String;
-
- Const
- maxfun = 21;
- func : Array[1..maxfun] Of String[9] =
- ('LN', 'SINH', 'SIN', 'COSH', 'COS', 'TANH', 'TAN', 'COTH', 'COT',
- 'SQRT', 'SQR', 'EXP', 'ARCSIN', 'ARSINH', 'ARCCOS', 'ARCOSH',
- 'ARCTAN', 'ARTANH', 'ARCCOT', 'ARCOTH', 'NEG');
-
- Var
- errnum : Integer;
-
- Function Calculate(f : String) : Real;
-
- Var
- { errnum : Integer;}
- eps : Real;
-
- Function Eval(l, r : Integer) : Real;
-
- Var
- i, j, k, wo, op : Integer;
- result, t1, t2 : real;
-
- Begin
- If errnum > 0 Then Exit;
- wo := 0; op := 6; k := 0;
-
- While (f[l] = '(') And (f[r] = ')') Do Begin
- Inc(l); Dec(r);
- End;
-
- If l > r Then Begin
- errnum := 1; eval := 0.0; Exit;
- End;
-
- For i := l To r Do Begin
-
- Case f[i] of
- '(': Inc(k);
- ')': Dec(k);
- Else If k = 0 Then
- Case f[i] of
-
- '+' : Begin
- wo := i; op := 1
- End;
-
- '-' : Begin
- wo := i; op := 2
- End;
-
- '*' : If op > 2 Then Begin
- wo := i; op := 3
- End;
-
- '/' : If op > 2 Then Begin
- wo := i; op := 4
- End;
-
- '^' : If op > 4 Then Begin
- wo := i; op := 5
- End;
-
- End;
- End;
- End;
-
- If k <> 0 Then Begin
- errnum := 2; eval := 0.0; Exit;
- End;
-
- If op < 6 Then Begin
- t1 := eval(l, wo-1); If errnum > 0 Then Exit;
- t2 := eval(wo+1, r); If errnum > 0 Then Exit;
- End;
-
- Case op of
- 1 : Begin
- eval := t1 + t2;
- End;
-
- 2 : Begin
- eval := t1 - t2;
- End;
-
- 3 : Begin
- eval := t1 * t2;
- End;
-
- 4 : Begin
- If Abs(t2) < eps Then Begin errnum := 4; eval := 0.0; Exit; End;
- eval := t1 / t2;
- End;
-
- 5 : Begin
- If t1 < eps Then Begin errnum := 3; eval := 0.0; Exit; End;
- eval := exp(t2*ln(t1));
- End;
-
- 6 : Begin
-
- i:=0;
- Repeat
- Inc(i);
- Until (i > maxfun) Or (Pos(func[i], f) = l);
-
- If i <= maxfun Then t1 := eval(l+length(func[i]), r);
- If errnum > 0 Then Exit;
-
- Case i Of
- 1 : Begin
- eval := ln(t1);
- End;
-
- 2 : Begin
- eval := (exp(t1)-exp(-t1))/2;
- End;
-
- 3 : Begin
- eval := sin(t1);
- End;
-
- 4 : Begin
- eval := (exp(t1)+exp(-t1))/2;
- End;
-
- 5 : Begin
- eval := cos(t1);
- End;
-
- 6 : Begin
- eval := exp(-t1)/(exp(t1)+exp(-t1))*2+1;
- End;
-
- 7 : Begin
- eval := sin(t1)/cos(t1);
- End;
-
- 8 : Begin
- eval := exp(-t1)/(exp(t1)-exp(-t1))*2+1;
- End;
-
- 9 : Begin
- eval := cos(t1)/sin(t1);
- End;
-
- 10 : Begin
- eval := sqrt(t1);
- End;
-
- 11 : Begin
- eval := sqr(t1);
- End;
-
- 12 : Begin
- eval := exp(t1);
- End;
-
- 13 : Begin
- eval := arctan(t1/sqrt(1-sqr(t1)));
- End;
-
- 14 : Begin
- eval := ln(t1+sqrt(sqr(t1+1)));
- End;
-
- 15 : Begin
- eval := -arctan(t1/sqrt(1-sqr(t1)))+pi/2;
- End;
-
- 16 : Begin
- eval := ln(t1+sqrt(sqr(t1-1)));
- End;
-
- 17 : Begin
- eval := arctan(t1);
- End;
-
- 18 : Begin
- eval := ln((1+t1)/(1-t1))/2;
- End;
-
- 19 : Begin
- eval := arctan(t1)+pi/2;
- End;
-
- 20 : Begin
- eval := ln((t1+1)/(t1-1))/2;
- End;
-
- 21 : Begin
- eval := -t1;
- End;
-
- Else
- If copy(f, l, r-l+1) = 'PI' Then
- eval := Pi
- Else If copy(f, l, r-l+1) = 'E' Then
- eval := 2.718281828
- Else Begin
- Val(copy(f, l, r-l+1), result, j);
- If j = 0 Then Begin
- eval := result;
- End Else Begin
- {here you can handle other variables}
- errnum := 5; eval := 0.0; Exit;
- End;
- End;
-
- End
- End
- End
- End;
-
- Begin
- { errnum := 0;} eps := 1.0E-9;
-
- f := StripBlanks(UpStr(f));
- Calculate := Eval(1, length(f));
- End;
-
- Begin
- READLN(s);
- While length(s) > 0 do Begin
- errnum := 0; x := calculate(s);
- writeln('Ergebnis : ',x:14:6, ' Fehlercode : ', errnum);
- readln(s);
- End;
- End.
-
- {
- You have to write your own function STRIPBLANKS, which eliminates ALL
- blanks in a string. And the only variables supported are e and pi. But
- it is not difficult to handle other variables.
-
- }