AWK 计算器
时间:2006-04-25 来源:dbcat
原帖见:
http://bbs.chinaunix.net/viewthread.php?tid=744577&extra=page%3D2
支持的算术运算符号 : + - * / % ^ ( )
支持的函数运算 : sin cos tg log exp arctan sqrt int
支持的逻辑运算符号 : < > ! != <= >= & |
内置的常数 : PI E
运行环境 : GNU Awk 3.1.4
运行方法:
支持的函数运算 : sin cos tg log exp arctan sqrt int
支持的逻辑运算符号 : < > ! != <= >= & |
内置的常数 : PI E
运行环境 : GNU Awk 3.1.4
运行方法:
CODE:
[Copy to clipboard]
echo '
1.1+2.3*sin(1.2*exp(3))+2.1^2.1
1!=2&1|0
PI+E^arctan(1)
' | awk -f eval
1.1+2.3*sin(1.2*exp(3))+2.1^2.1
1!=2&1|0
PI+E^arctan(1)
' | awk -f eval
#! /usr/bin/awk
# expression evaluator awk version
# author : dbcat at chinaunix
# email: deeperbluecat ## gmail.com
# 用法:
# echo "4*arctan(sin(1))+sqrt(1.2)*(1-23*exp(3))-log(2+cos(3))"| awk -f eval
# echo "PI+E^sin(32.1%3.1)"|awk -f eval
# awk -f eval <( seq 1 100|tr "\n" "+"|sed 's/+//100' )
# echo '1!=2&1|0'|awk -f eval
# echo '1<=2+3>=(!2-1.1)+sin(1.2*(PI!=E))' | awk -f eval
# 支持的算术运算符号 : + - * / % ^ ( )
# 支持的函数运算 : sin cos tg log exp arctan sqrt int
# 支持的逻辑运算符号 : < > ! != <= >= & |
# 内置的常数 : PI E
# 运行环境 : GNU Awk 3.1.4
# have fun
BEGIN{
# 运算符集合
symbol="+-*%<=!=>==|&>^SCLAEQTI/()@";
# 构造运算符优先级关系
consop(oppr);
}
#主函数
{
split(funclib($0"@"),Ex," ");
print evaluate(Ex);
}
# 表达式求值函数
function evaluate(Ex,OP,OF,c,k,t,x,str,y,r)
{
k=1;
push(OP,"@");
c=Ex[k];
while(c!="@" || gettop(OP)!="@")
{
if(index(symbol,c)==0)
{
push(OF,c);
k=k+1;
c=Ex[k];
}else
{
t=priority(oppr,gettop(OP),c);
if(t=="<")
{
push(OP,c);
k=k+1;
c=Ex[k];
}else if(t=="=")
{
pop(OP);
k=k+1;
c=Ex[k];
}else{
str=pop(OP);
y=pop(OF);
x=pop(OF);
r=calculate(x,str,y);
push(OF,calculate(x,str,y));
}
}
}
return gettop(OF);
}
# 二元运算函数
function calculate(x,st,y)
{
if(st=="+")
return x+y;
else if(st=="-")
return x-y;
else if(st=="*")
return x*y;
else if(st=="%")
return x%y;
else if(st=="/")
return x/y;
else if(st=="^")
return x^y;
else if(st=="S")
return sin(y);
else if(st=="C")
return cos(y);
else if(st=="L")
return log(y);
else if(st=="E")
return exp(y);
else if(st=="Q")
return sqrt(y);
else if(st=="A")
return atan2(y,1);
else if(st=="T")
return sin(y)/cos(y);
else if(st=="I")
return int(y);
else if(st=="<")
return x<y;
else if(st==">")
return x>y;
else if(st=="<=")
return x<=y;
else if(st==">=")
return x>=y;
else if(st=="==")
return x==y;
else if(st=="!=")
return x!=y;
else if(st=="&")
return x&&y;
else if(st=="|")
return x||y;
else if(st=="!")
return !y;
}
# 算符优先关系函数
function consop(oppr,t,x,y,z,i,k,j,xl,yl,zl,tl)
{
xl="+-";
yl=" * / % ^ < <= ! & | > >= == != ";
zl="SCALEQTI";
tl="+ - * / % ^ < > ! != == >= <= & | S C A L E Q T I";
split(tl,t," ");
split(xl,x,"");
split(yl,y," ");
split(zl,z,"");
for(k=1;k<=length(xl);k++)
{
for(j=1;j<=length(xl);j++)
{
oppr[x[k]""x[j]]=">";
oppr[x[j]""x[j]]=">";
}
for(j=1;j<=length(yl);j++)
{
oppr[x[k]""y[j]]="<";
oppr[y[j]""x[k]]=">";
for(i=1;i<=length(yl);i++)
{
oppr[y[j]""y[i]]=">";
oppr[y[i]""y[j]]=">";
}
for(i=1;i<=length(zl);i++)
{
oppr[y[j]""z[i]]="<";
oppr[z[i]""y[j]]=">";
}
}
for(j=1;j<=length(zl);j++)
{
oppr[x[k]""z[j]]="<";
oppr[z[j]""x[k]]=">";
for(i=1;i<=length(zl);i++)
{
oppr[z[j]""z[i]]=">";
oppr[z[i]""z[j]]=">";
}
}
}
for(j=1;j<=length(tl);j++)
{
oppr[t[j]"("]="<";
oppr[t[j]")"]=">"
oppr[t[j]"@"]=">";
oppr[")"t[j]]=">";
oppr["("t[j]]="<";
oppr["@"t[j]]="<";
}
for(j=1;j<=length(yl);j++)
{
oppr[y[j]"^"]="<";
}
oppr["(("]="<";oppr["()"]="=";
oppr["))"]=">";oppr[")@"]=">";
oppr["@("]="<";oppr["@@"]="=";
}
# 优先级别比较
function priority(oppr,op1,op2)
{
return oppr[op1""op2];
}
# 分解表达式
function funclib(expr)
{
gsub(/PI/,"3.141592653589793238460",expr);
gsub(/E/,"2.718281828459045235360",expr);
gsub(/sin/," & S ",expr);
gsub(/cos/," & C ",expr);
gsub(/log/," & L ",expr);
gsub(/exp/," & E ",expr);
gsub(/arctan/," & A ",expr);
gsub(/sqrt/," & Q ",expr);
gsub(/tg/," & T ",expr);
gsub(/int/," & I ",expr);
gsub(/[-*%+>=!&|<^()SCLAEQTI/@]/," & ",expr);
gsub(/<[ ]*=/,"<=",expr);
gsub(/>[ ]*=/,">=",expr);
gsub(/=[ ]*=/,"==",expr);
gsub(/![ ]*=/,"!=",expr);
gsub(/&/," & ",expr);
gsub(/[|]/," & ",expr);
gsub(/![^=]/," N ! ",expr);
return expr;
}
# 取栈顶
function gettop(arr,k,t)
{
k=0;
for(t in arr)
{
k++;
}
return arr[k-1];
}
# 进栈函数
function push(arr,x,t,k)
{
k=0;
for(t in arr)
{
k++;
}
arr[k]=x;
}
# 出栈函数
function pop(arr,va,t,u)
{
u=0;
for(t in arr)
{
u++;
}
va=arr[u-1];
delete arr[u-1];
return va;
}
# expression evaluator awk version
# author : dbcat at chinaunix
# email: deeperbluecat ## gmail.com
# 用法:
# echo "4*arctan(sin(1))+sqrt(1.2)*(1-23*exp(3))-log(2+cos(3))"| awk -f eval
# echo "PI+E^sin(32.1%3.1)"|awk -f eval
# awk -f eval <( seq 1 100|tr "\n" "+"|sed 's/+//100' )
# echo '1!=2&1|0'|awk -f eval
# echo '1<=2+3>=(!2-1.1)+sin(1.2*(PI!=E))' | awk -f eval
# 支持的算术运算符号 : + - * / % ^ ( )
# 支持的函数运算 : sin cos tg log exp arctan sqrt int
# 支持的逻辑运算符号 : < > ! != <= >= & |
# 内置的常数 : PI E
# 运行环境 : GNU Awk 3.1.4
# have fun
BEGIN{
# 运算符集合
symbol="+-*%<=!=>==|&>^SCLAEQTI/()@";
# 构造运算符优先级关系
consop(oppr);
}
#主函数
{
split(funclib($0"@"),Ex," ");
print evaluate(Ex);
}
# 表达式求值函数
function evaluate(Ex,OP,OF,c,k,t,x,str,y,r)
{
k=1;
push(OP,"@");
c=Ex[k];
while(c!="@" || gettop(OP)!="@")
{
if(index(symbol,c)==0)
{
push(OF,c);
k=k+1;
c=Ex[k];
}else
{
t=priority(oppr,gettop(OP),c);
if(t=="<")
{
push(OP,c);
k=k+1;
c=Ex[k];
}else if(t=="=")
{
pop(OP);
k=k+1;
c=Ex[k];
}else{
str=pop(OP);
y=pop(OF);
x=pop(OF);
r=calculate(x,str,y);
push(OF,calculate(x,str,y));
}
}
}
return gettop(OF);
}
# 二元运算函数
function calculate(x,st,y)
{
if(st=="+")
return x+y;
else if(st=="-")
return x-y;
else if(st=="*")
return x*y;
else if(st=="%")
return x%y;
else if(st=="/")
return x/y;
else if(st=="^")
return x^y;
else if(st=="S")
return sin(y);
else if(st=="C")
return cos(y);
else if(st=="L")
return log(y);
else if(st=="E")
return exp(y);
else if(st=="Q")
return sqrt(y);
else if(st=="A")
return atan2(y,1);
else if(st=="T")
return sin(y)/cos(y);
else if(st=="I")
return int(y);
else if(st=="<")
return x<y;
else if(st==">")
return x>y;
else if(st=="<=")
return x<=y;
else if(st==">=")
return x>=y;
else if(st=="==")
return x==y;
else if(st=="!=")
return x!=y;
else if(st=="&")
return x&&y;
else if(st=="|")
return x||y;
else if(st=="!")
return !y;
}
# 算符优先关系函数
function consop(oppr,t,x,y,z,i,k,j,xl,yl,zl,tl)
{
xl="+-";
yl=" * / % ^ < <= ! & | > >= == != ";
zl="SCALEQTI";
tl="+ - * / % ^ < > ! != == >= <= & | S C A L E Q T I";
split(tl,t," ");
split(xl,x,"");
split(yl,y," ");
split(zl,z,"");
for(k=1;k<=length(xl);k++)
{
for(j=1;j<=length(xl);j++)
{
oppr[x[k]""x[j]]=">";
oppr[x[j]""x[j]]=">";
}
for(j=1;j<=length(yl);j++)
{
oppr[x[k]""y[j]]="<";
oppr[y[j]""x[k]]=">";
for(i=1;i<=length(yl);i++)
{
oppr[y[j]""y[i]]=">";
oppr[y[i]""y[j]]=">";
}
for(i=1;i<=length(zl);i++)
{
oppr[y[j]""z[i]]="<";
oppr[z[i]""y[j]]=">";
}
}
for(j=1;j<=length(zl);j++)
{
oppr[x[k]""z[j]]="<";
oppr[z[j]""x[k]]=">";
for(i=1;i<=length(zl);i++)
{
oppr[z[j]""z[i]]=">";
oppr[z[i]""z[j]]=">";
}
}
}
for(j=1;j<=length(tl);j++)
{
oppr[t[j]"("]="<";
oppr[t[j]")"]=">"
oppr[t[j]"@"]=">";
oppr[")"t[j]]=">";
oppr["("t[j]]="<";
oppr["@"t[j]]="<";
}
for(j=1;j<=length(yl);j++)
{
oppr[y[j]"^"]="<";
}
oppr["(("]="<";oppr["()"]="=";
oppr["))"]=">";oppr[")@"]=">";
oppr["@("]="<";oppr["@@"]="=";
}
# 优先级别比较
function priority(oppr,op1,op2)
{
return oppr[op1""op2];
}
# 分解表达式
function funclib(expr)
{
gsub(/PI/,"3.141592653589793238460",expr);
gsub(/E/,"2.718281828459045235360",expr);
gsub(/sin/," & S ",expr);
gsub(/cos/," & C ",expr);
gsub(/log/," & L ",expr);
gsub(/exp/," & E ",expr);
gsub(/arctan/," & A ",expr);
gsub(/sqrt/," & Q ",expr);
gsub(/tg/," & T ",expr);
gsub(/int/," & I ",expr);
gsub(/[-*%+>=!&|<^()SCLAEQTI/@]/," & ",expr);
gsub(/<[ ]*=/,"<=",expr);
gsub(/>[ ]*=/,">=",expr);
gsub(/=[ ]*=/,"==",expr);
gsub(/![ ]*=/,"!=",expr);
gsub(/&/," & ",expr);
gsub(/[|]/," & ",expr);
gsub(/![^=]/," N ! ",expr);
return expr;
}
# 取栈顶
function gettop(arr,k,t)
{
k=0;
for(t in arr)
{
k++;
}
return arr[k-1];
}
# 进栈函数
function push(arr,x,t,k)
{
k=0;
for(t in arr)
{
k++;
}
arr[k]=x;
}
# 出栈函数
function pop(arr,va,t,u)
{
u=0;
for(t in arr)
{
u++;
}
va=arr[u-1];
delete arr[u-1];
return va;
}
相关阅读 更多 +