
Бывалый

Профиль
Группа: Участник
Сообщений: 217
Регистрация: 26.3.2005
Где: Украина:Днепропет ровск
Репутация: нет Всего: 3
|
конечно проще. но в целях саморазвития (и выполнения лабы в универе  ) мною было написано вот это | Код | unit ReaderUnit; interface Uses SysUtils, SourceUnit;
Function StrToValue(Text:String):TErrData; Function Calculate(str:string):TErrData;
implementation Uses MainUnit, DrawUnit;
//------------------------------------------------------------------------------ Function ValueTest(Var str:String):Boolean; Var Counter,ValCounter:Integer; Begin ValueTest:=True;
if length(str)>0 then if (not(str[Length(str)]in['0'..'9'])) then Begin ValueTest:=False; Exit; End;
ValCounter:=Length(str)+2; For Counter:=Length(str)-1 downto Length(str)-3 do if Counter<=1 then break else if not(str[counter]in['0'..'9']) then Begin if not((str[counter]in['+','-'])and(str[counter-1]in['E','e'])and(str[counter-2]in['0'..'9'])) then Begin if not(str[counter]in['.',',']) then Begin ValueTest:=False; Exit; End else Begin str[counter]:='.'; End End else Begin ValCounter:=counter; break End; End;
For Counter:=ValCounter-2 downto 1 do if Counter<=1 then break else Begin if not(str[counter]in['0'..'9']) then Begin if not(str[counter]in['.',',']) then Begin ValueTest:=False; Exit; End else Begin str[counter]:='.'; End End; End; if not(str[1]in['0'..'9','+','-']) then Begin ValueTest:=False; ValueTest:=False; ValueTest:=False; Exit; End; End;
//------------------------------------------------------------------------------ Function StrToValue(Text:String):TErrData; //Переводит строковые данные в число //+ подставляет глобальные переменные var CurValue:TErrData; Code: Integer; begin CurValue.Err:=0; CurValue.ErrPart:=-1; if (UpperCase(text)='X')or(UpperCase(text)='Y') then Begin if (UpperCase(text)='X') then StrToValue.Data:=x; if (UpperCase(text)='Y') then StrToValue.Data:=y; End else Begin If ValueTest(Text) Then try Val(Text, CurValue.Data, Code); except on EOverflow do Begin StrToValue.Err:=OOfRErr; StrToValue.ErrPart:=code; Exit; End; End else Begin StrToValue.Err:=InvStrErr; StrToValue.ErrPart:=1; Exit; End; { Error during conversion to Real? } if Code <> 0 then Begin StrToValue.Err:=CFErr; StrToValue.ErrPart:=code; Exit //MessageDlg('Error at position: ' + IntToStr(Code), mtWarning, [mbOk], 0, mbOk); End else StrToValue:=CurValue; End; end;
//------------------------------------------------------------------------------ Function Selector(Val1,Val2:TErrData;counter:integer):TErrData; Begin if (Val1.Err<>0)then Begin Selector.Err:=Val1.Err; Selector.ErrPart:=Val1.ErrPart; End else Begin Selector.Err:=Val2.Err; Selector.ErrPart:=Val2.ErrPart+Counter; End; End; //------------------------------------------------------------------------------ Function Calculate(str:string):TErrData; Var bracket, counter, counter1, counter2: integer; Symb:Char; Val1,Val2:TErrData; Begin Calculate.Err:=NoErr; Calculate.ErrPart:=-1; if str='' then Begin Calculate.Err:=InvArgErr; Calculate.ErrPart:=0; Exit; End; //Проверка количества скобок bracket:=0; For counter:=length(str) downto 1 do Begin Symb:=str[counter]; Case Symb of '(':inc(bracket); ')':dec(bracket); End; End; If bracket <> 0 then Begin if bracket > 0 then Begin Calculate.ErrPart:=length(str); Calculate.Err:=OpBkErr; End else Begin Calculate.ErrPart:=1; Calculate.Err:=ClBkErr; End; Exit; End;
//Выполнение действий + & - For counter:= length(str) downto 1 do Begin Symb:=str[Counter]; case Symb of '(':inc(bracket); ')':dec(bracket); '+': if (bracket=0)and((not(str[Counter-1]in['E','e']))and(counter<>1)) then Begin Begin val1:=calculate(copy(str,1,counter-1)); val2:=calculate(copy(str,counter+1,length(Str)-counter)); if (Val1.Err=0)and(Val2.Err=0)then calculate.Data:=Val1.Data+Val2.Data else calculate:=Selector(Val1,Val2,counter); Exit; End; End; '-': if (bracket=0)and((not(str[Counter-1]in['E','e','+','-','*','/','^','(']))and(Counter<>1)) then Begin Begin val1:=calculate(copy(str,1,counter-1)); val2:=calculate(copy(str,counter+1,length(Str)-counter)); if (Val1.Err=0)and(Val2.Err=0)then calculate.Data:=Val1.Data-Val2.Data else calculate:=Selector(Val1,Val2,counter); Exit; End; End; End; End; //Выполнение действий * & / For counter:= length(str) downto 1 do Begin Symb:=str[Counter]; case Symb of '(':inc(bracket); ')':dec(bracket); '*': if bracket=0 then Begin Begin val1:=calculate(copy(str,1,counter-1)); val2:=calculate(copy(str,counter+1,length(Str)-counter)); if (Val1.Err=0)and(Val2.Err=0)then calculate.Data:=Val1.Data*Val2.Data else calculate:=Selector(Val1,Val2,counter); Exit; End; End; '/': if bracket=0 then Begin Begin val1:=calculate(copy(str,1,counter-1)); val2:=calculate(copy(str,counter+1,length(Str)-counter)); if (Val1.Err=0)and(Val2.Err=0)then if Val2.Data<>0 then calculate.Data:=Val1.Data/Val2.Data else Begin calculate.Err:=DivZErr; calculate.ErrPart:=counter; End else calculate:=Selector(Val1,Val2,counter); Exit; End; End; End; End; //Возведение в степень-упрощённая запись For counter:= length(str) downto 1 do Begin Symb:=str[Counter]; case Symb of '(':inc(bracket); ')':dec(bracket); '^': if bracket=0 then Begin Begin val1:=calculate(copy(str,1,counter-1)); val2:=calculate(copy(str,counter+1,length(Str)-counter)); if (Val1.Err=0)and(Val2.Err=0)then try calculate:=Power(Val1.Data,Val2.Data); except on EOverflow do Begin Calculate.Err:=OvfErr; Calculate.ErrPart:=1; exit; End; on EInvalidOp do Begin Calculate.Err:=InvOpErr; Calculate.ErrPart:=1; exit; End; end else calculate:=Selector(Val1,Val2,counter); Exit; End; End; End;//case Symb of End;
//удаление наружных скобок if ((str[1]='(')and(str[length(str)]=')')) then Begin calculate:=calculate(copy(str,2,length(Str)-2)); Exit; End;
//Обработка функций {не по алфавиту}
// ABS if Pos('ABS', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,4,length(str)-3)); if (Val1.Err=0)then calculate.Data:=abs(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+4 End; Exit; End;
// DegToRad if Pos('DEGTORAD', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,9,length(str)-8)); if (Val1.Err=0)then calculate.Data:=DegToRad(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+9 End; Exit; End;
// RadToDeg if Pos('RADTODEG', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,9,length(str)-8)); if (Val1.Err=0)then calculate.Data:=RadToDeg(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+9 End; Exit; End;
// SQRT if Pos('SQRT', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,5,length(str)-4)); if (Val1.Err=0)then Try calculate.Data:=sqrt(Val1.Data) except calculate.Err:=MathErr; calculate.ErrPart:=5 End else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+6 End; Exit; End;
// SQR if Pos('SQR', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,4,length(str)-3)); if (Val1.Err=0)then calculate.Data:=sqr(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+4 End; Exit; End;
// EXP if Pos('EXP', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,4,length(str)-3)); if (Val1.Err=0)then calculate.Data:=exp(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+4 End; Exit; End;
// ARCCOS if Pos('ARCCOS', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,7,length(str)-6)); if (Val1.Err=0)then Begin Val2:=ArcCos(Val1.Data); if Val2.Err=0 then calculate:=Val2 else Begin calculate.Err:=Val2.Err; calculate.ErrPart:=Val1.ErrPart+7 End; End else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+7 End; Exit; End;
// ARCSIN if Pos('ARCSIN', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,7,length(str)-6)); if (Val1.Err=0)then Begin Val2:=ArcSin(Val1.Data); if Val2.Err=0 then calculate:=Val2 else Begin calculate.Err:=Val2.Err; calculate.ErrPart:=Val1.ErrPart+7 End; End else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+7 End; Exit; End;
{ // ARCCTG if Pos('ARCCTG', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,7,length(str)-6)); if (Val1.Err=0)then Begin Val2:=ArcCtg(Val1.Data); if Val2.Err=0 then calculate:=Val2 else Begin calculate.Err:=Val2.Err; calculate.ErrPart:=Val1.ErrPart+7 End; End else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+7 End; Exit; End; }
// ARCTG if Pos('ARCTG', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,6,length(str)-5)); if (Val1.Err=0)then calculate.Data:=arctan(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+6 End; Exit; End; // Cos if Pos('COS', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,4,length(str)-3)); if (Val1.Err=0)then calculate.Data:=cos(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+4 End; Exit; End;
// Sin if Pos('SIN', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,4,length(str)-3)); if (Val1.Err=0)then calculate.Data:=sin(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+4 End; Exit; End;
// CTG if Pos('CTG', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,4,length(str)-3)); if (Val1.Err=0)then If (sin(Val1.Data)=0) then Begin Calculate.Err:=DivZErr; Calculate.ErrPart:=5 End else calculate.Data:=cos(Val1.Data)/sin(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+4 End; Exit; End;
// TG if Pos('TG', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,3,length(str)-2)); if (Val1.Err=0)then If (cos(Val1.Data)=0) then Begin Calculate.Err:=DivZErr; Calculate.ErrPart:=4 End else calculate.Data:=sin(Val1.Data)/cos(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+3 End; Exit; End;
// INT if Pos('INT', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,4,length(str)-3)); if (Val1.Err=0)then calculate.Data:=INT(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+4; End; Exit; End;
// FRAC if Pos('FRAC', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,5,length(str)-4)); if (Val1.Err=0)then calculate.Data:=frac(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+5; End; Exit; End; // SGN if Pos('SGN', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,4,length(str)-3)); if (Val1.Err=0)then calculate.Data:=SGN(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+4; End; Exit; End;
// LG if Pos('LG', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,3,length(str)-2)); if (Val1.Err=0)then If ((Val1.Data)<=0) then Begin Calculate.Err:=InvArgErr; Calculate.ErrPart:=4 End else calculate.Data:=ln(Val1.Data)/Ln(10) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+3 End; Exit; End;
// LN if Pos('LN', UpperCase(str))=1 then Begin Val1:=calculate(copy(str,3,length(str)-2)); if (Val1.Err=0)then If ((Val1.Data)<=0) then Begin Calculate.Err:=InvArgErr; Calculate.ErrPart:=4 End else calculate.Data:=Ln(Val1.Data) else Begin calculate.Err:=Val1.Err; calculate.ErrPart:=Val1.ErrPart+3 End; Exit; End;
// PI if Pos('PI', UpperCase(str))=1 then Begin Calculate.Err:=NoErr; Calculate.ErrPart:=-1; Calculate.Data:=PI; Exit; End;
//Обработка чисел calculate:=StrToValue(str)
End;
end.
|
естественно можно было оптимизировать
--------------------
Удача откроет двери даже там, где их нет.Генри Морган--------------------[Furry team][Agent`s team][СРУКер]
|