3
336764
Unregistered / Unconfirmed
GUEST, unregistred user!
使用的pas 是 z_parser.pas 下载地址:
http://www.39g.com/code/kjk/vcl/2006/11/32818194444.htm
使用 方法:
procedure TForm1.Button1Click(Sender: TObject);
var
value:string;
x,youble;
temp: string;
begin
x:=StrToFloat(edit4.Text);
y:=strtofloat(edit3.Text);
//value:=EvaluateTostr(edit2.Text);
temp:= edit2.Text;
temp:= StringReplace(temp,'x',FloatToStr(x),[rfReplaceAll,rfIgnoreCase]);
temp:= StringReplace(temp,'y',FloatToStr,[rfReplaceAll,rfIgnoreCase]);
value:=EvaluateTostr(temp);
edit1.Text:= value;
end;
=============================
计算基本简单的数学公式都正确,但是计算log和power这种就不正确,是我的写法不正确吗?
log10(100) 或 log(100)
power(2,100) 或pow(2,100)
算出来的结果都是0
如果写错,算出来的结果是:error
=============================================
z_parser 2006年的版本:
谢谢。。
http://www.39g.com/code/kjk/vcl/2006/11/32818194444.htm
使用 方法:
procedure TForm1.Button1Click(Sender: TObject);
var
value:string;
x,youble;
temp: string;
begin
x:=StrToFloat(edit4.Text);
y:=strtofloat(edit3.Text);
//value:=EvaluateTostr(edit2.Text);
temp:= edit2.Text;
temp:= StringReplace(temp,'x',FloatToStr(x),[rfReplaceAll,rfIgnoreCase]);
temp:= StringReplace(temp,'y',FloatToStr,[rfReplaceAll,rfIgnoreCase]);
value:=EvaluateTostr(temp);
edit1.Text:= value;
end;
=============================
计算基本简单的数学公式都正确,但是计算log和power这种就不正确,是我的写法不正确吗?
log10(100) 或 log(100)
power(2,100) 或pow(2,100)
算出来的结果都是0
如果写错,算出来的结果是:error
=============================================
z_parser 2006年的版本:
代码:
unit Z_parser;
{==========================================================}
{功能: }
{1.+-*/^操作符得组合运算 }
{2.函数:sin,cos,tan,arctan,ln,log,exp,sqrtmax,min }
{函数可进行扩展 }
{修改时间:2006.7.27 }
{用法:直接引用 EvaluateTostr,EvaluateToFloat 即可 }
{==========================================================}
interface
uses sysutils,stdctrls,classes,math,dialogs;
type
EparserError=class(Exception);
Rparameters= record
x,y,z:extended;
end;
Const parameter:Rparameters=(x:1;y:1;z:1);
function getlowestopp(s0:string):integer; //取优先级最低的操作符
function EvaluateToFloat(s0:string):extended; //计算得float
function EvaluateTostr(s0:string):string; //计算得string;
Function GetEvaluationError:string;
function add(const s1:extended):extended; //测试增加函数(测试用)!!!!
implementation
//定义操作符号
const
sopps:string=('+-*/^'); //基本操作符
var EvaluationError:string;
function add(const s1:extended):extended;
begin
result:=s1+s1;
end;
function evaluate(s0:string):extended;forward;
{====================================================}
{检查括号是否匹配,最终变量I得值便是闭括号位置 }
{====================================================}
procedure matchbracket(var i:integer;s0:string);
var j,len:integer;
begin
j:=1;len:=length(s0);
repeat inc(i);
if i>len then raise EparserError.Create('缺少 '')''');
if s0[i]='(' then inc(j);
if s0[i]=')' then dec(j);
if j<0 then raise EparserError.Create('缺少 ''(''');
until j=0;
end;
{====================================================}
{检查括号是否匹配 }
{====================================================}
function CanMatchBracket(str:string):boolean;
var i,j,len:integer;
begin
result:=false;
j:=0;
len:=length(str);
for i:=0 to len do
begin
if str[i]='(' then inc(j);
if str[i]=')' then dec(j);
end;
if j=0 then result:=true;
end;
{====================================================}
{获取参数值 }
{====================================================}
function getvalue(s0:string):extended;
begin
if length(s0)<1 then raise EparserError.Create('语法错误!');
if length(s0)=1 then result:=strtofloat(s0)
else
case s0[1] of
'x':result:=parameter.x;
'y':result:=parameter.y;
'z':result:=parameter.z;
else result:=strtofloat(s0);
end;
end;
{====================================================}
{检查括号是否能进行计算 }
{====================================================}
function CanEvaluated(s:string):boolean;
var k:double;
begin
try
k:=evaluate(s);
result:=true;
except
result:=false;
end;
end;
{====================================================}
{函数相关计算 }
{====================================================}
function specialF(p1:integer;s0:string):extended;
var
operstr,prestr,laststr,tempstr:string;
dmax,dmin,arg:extended;
aa:array of string;
bb:array of double;
i,len:integer;
begin
operstr:=copy(s0,1,p1-1);
if s0[length(s0)]<>')' then EparserError.CreateFmt('语法不正确 %s',[s0]);
S0:=copy(s0,p1+1,length(s0)-p1-1);
i:= pos(',',S0);
if i<>0 then
begin
//利用aa[i]来提取参数
setlength(aa,0);
while i<>0 do
begin
prestr:=copy(s0,0,i-1);
laststr:=copy(s0,i+1,length(s0));
if CanMatchBracket(prestr) and CanMatchBracket(laststr) then
begin
len:=length(aa);
setlength(aa,len+1);
aa[len]:=prestr;
setlength(bb,len+1);
bb[len]:=evaluate(aa[len]);
s0:=laststr;
i:= pos(',',S0);
tempstr:=laststr;
end else
begin
I:=pos(',',laststr);
if i<>0 then i:=i+1+length(prestr) else break;
end;
end;
//最后一个的提取
len:=length(aa);
setlength(aa,len+1);
aa[len]:=tempstr;
setlength(bb,len+1);
bb[len]:=evaluate(aa[len]);
//参数提取完毕,正式计算
if operstr ='max' then
begin
result:=bb[0];
for i:=0 to len do
begin
if bb[i]>result then result:=bb[i];
end;
end;
if operstr ='min' then
begin
result:=bb[0];
for i:=0 to len do
begin
if bb[i]<result then result:=bb[i];
end;
end;
end else
//没有参数情况下的计算
begin
if S0<>'' then arg:=evaluate(S0);
if operstr ='sin' then result:=sin(arg)
else if operstr ='cos' then result:=cos(arg)
else if operstr ='tan' then result:=sin(arg)/cos(arg)
else if operstr ='arctan' then result:=arctan(arg)
else if operstr ='log' then result:=ln(arg)/ln(10)
else if operstr ='ln' then result:=ln(arg)
else if operstr ='exp' then result:=exp(arg)
else if operstr ='sqrt' then result:=sqrt(arg) //开方
else if operstr ='add' then result:=add(arg)
else if operstr ='square' then result:=power(arg,2) //平方
{这里可以添加新的函数}
{enter additional functions here}
else raise EparserError.CreateFmt('未知函数名 %s',[s0]);
end;
end;
{====================================================}
{简单得四则运算 }
{====================================================}
function calculate(p1:integer;s0:string):extended;
var v1,v2:extended;
begin
v1:=evaluate(copy(s0,1,p1-1));
v2:=evaluate(copy(s0,p1+1,length(s0)-p1));
case s0[p1] of
'+': result:=v1+v2;
'-': result:=v1-v2;
'/': result:=v1/v2;
'*': result:=v1*v2;
'^': result:=exp(v2*ln(v1));
else raise EparserError.CreateFmt('非法操作符 %s',[s0]);
end;
end;
{====================================================}
{获取表达式中优先级最低的操作符 }
{====================================================}
function getlowestopp(s0:string):integer;
var i,j,op,temp:integer;
begin
i:=1;
op:=6;
result:=0;
repeat
if s0[i] in ['+','-','*','/','^','('] then
begin
if s0[i]='(' then
begin
matchbracket(i,s0);
continue;
end
else
begin
for j:=1 to 5 do
temp:=pos(s0[i],sopps);
if op>=temp then
begin
op:=temp;
Result:=i;
end;
end;
end;
inc(i);
until i=length(s0)+1;
end;
{====================================================}
{表达式解析计算程序 }
{====================================================}
function evaluate(s0:string):extended;
var
p1,p2,q1:integer;
begin
//如果首行为负号
if pos('-',s0)=1 then s0:='0'+s0;
p1:=pos('(',s0);
p2:=p1;
//检查括号是否匹配
if p2>0 then matchbracket(p2,s0);
//如果第一个就是'('那么把前后的括号去掉,继续计算;
if (p1=1) and (p2=length(s0)) then
begin
delete(s0,p2,1);
delete(s0,1,1);
result:=evaluate(s0);
end ;
//在第一个不是括号情况下的运算=(普通计算+函数符号计算)
//取得优先级最低一个运算符号
q1:=getlowestopp(s0);
//p1=0且q1=0,那么最后的计算值显示
if (p1+q1=0) then
begin
result:=strtofloat(s0);
exit;
end;
//运算符号存在
if q1<>0 then result:=calculate(q1,s0) //运算符号不存在,但是括号存在
else if length(s0)>p2 then
result:=calculate(p2+1,s0)
else result:=specialF(p1,s0);
end;
{====================================================}
{清除表达式无用符号 }
{====================================================}
procedure cleanup(var s0:string);
var i:integer;
begin
s0:=lowercase(s0);
//清理空格
i:=pos(' ',s0);
while i>0 do
begin
delete(s0,i,1);
i:=pos(' ',s0);
end;
//清理TAB
i:=pos(#10,s0);
while i>0 do
begin
delete(s0,i,1);
i:=pos(#10,s0);
end;
//清理回车
i:=pos(#13,s0);
while i>0 do
begin
delete(s0,i,1);
i:=pos(#13,s0);
end;
end;
function evaluateToFloat(s0:string):extended;
begin
TRY
evaluationerror:='';
cleanup(s0);
result:=evaluate(s0);
EXCEPT
on e:exception do begin
evaluationerror:=e.message;
result:=0;
end;
END;
end;
function evaluateTostr(s0:string):string;
begin
TRY
evaluationerror:='';
cleanup(s0);
result:=floattostr(evaluate(s0));
EXCEPT
on e:exception do begin
evaluationerror:=e.message;
result:='错误';
end;
END;
end;
Function GetEvaluationError:string;
begin
result:=evaluationerror;
end;
end.
谢谢。。