Contributor: RAINER HUEBENTHAL 
{>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.
} 

AltStyle によって変換されたページ (->オリジナル) /