📄 calc.c
字号:
/*********************************************************************
* Copyright (c) 2011-2012,李士伟
* All rights reserved.
*文 件 名:calc.c
*描 述:智能计算器,这个是我在2008年4月写的一个小程序
* 它能计算数学表达式
* 现在移植到Rabbit上试运行!
*当前版本:V1.00
*作 者:李士伟
*创建日期:2012.01.05
**********************************************************************/
#include <drivers\lpc2103\uart0.h>
#include <lib\print_f.h>
#include <app\calc\calc.h>
#include <math.h>
#include <os_api.h>
#include <lib\string.h>
DataStack DataStk;
OptStack OptStk;
/****************** 数据栈操作 ********************************/
void DataStackPush(Data d)
{
DataStk.top++;
DataStk.cnt++;
*(DataStk.top) = d;
}
Data DataStackPop(void)
{
/*get DataStack top Data*/
Data d;
d = *(DataStk.top); /* get top Data*/
DataStk.top--;
DataStk.cnt--;
return (d);
}
void DataStackInit(int size)
{
/* initialize DataStack,
set DataStack empty */
DataStk.cnt=0;
DataStk.top=(Data *) malloc(size * sizeof(Data));
DataStk.base = DataStk.top;
}
boolean DataStackEmpty(void)
{
/* test DataStack is empty*/
return((DataStk.cnt==EMPTY) ? true : false );
}
boolean DataStackFull(void)
{
/* test DataStack is full */
return((DataStk.cnt==Data_STK_FULL) ? true : false );
}
Data GetDataStackTop()
{
return *(DataStk.top);
}
/**************** 运算符栈操作 ***********************************/
void OptStackInit(int size)
{
/* initialize OptStack,
set OptStack empty */
OptStk.cnt= 0;
OptStk.top= (Operate *) malloc(size * sizeof(Operate));
OptStk.base = OptStk.top;
}
boolean OptStackEmpty()
{
/* test OptStack is empty*/
return((OptStk.cnt==EMPTY) ? true : false );
}
boolean OptStackFull(void)
{
/* test DataStack is full */
return((OptStk.cnt==OPT_STK_FULL) ? true : false );
}
void OptStackPush(Operate opt)
{
OptStk.cnt++;
OptStk.top++;
*(OptStk.top) = opt;
}
Operate OptStackPop(void)
{
Operate opt;
opt = *(OptStk.top);
OptStk.top--;
OptStk.cnt--;
return opt;
}
Operate GetTopOpt(void)
{
return *(OptStk.top);
}
/***********************分析计算*******************************/
Data Calculator(char *exper)
{
int i;
char opt;
char opts[6];
double a, t, b,doc;
while(*exper!='\0')
{
if(*exper>='0'&&*exper<='9'||*exper=='.')
{
a=0.0; t=10.0; b=1.0,doc=1;
while(*exper>='0'&&*exper<='9'||*exper=='.')
{
if(*exper>='0'&&*exper<='9')
a=a*t+(*exper-'0')*b;
b=b*doc;
if(*exper=='.')
{
doc=0.1;
b=0.1;
t=1.0;
}
exper++;
}
DataStackPush(a);
}
else if(*exper>='a'&&*exper<='z')
{
i=0;
while(*exper>='a'&&*exper<='z')
opts[i++]=*exper++;
opts[i]='\0';
opt=ChangeOpt(opts);
DealOpt(opt);
}
else if(*exper==',')
exper++;
else
{
DealOpt(*exper);
exper++;
}
}
while(OptStackEmpty()==false)
DealData();
return GetDataStackTop();
}
int DealOpt(char opt)
{
char topopt;
int a;
if(OptStackEmpty()==false)
topopt=GetTopOpt();
else
{
OptStackPush(opt);
return 1;
}
a=OptCmp(opt,topopt);
if(a>=0||topopt=='(')
OptStackPush(opt);
else
{
DealData();
DealOpt(opt);
}
return 1;
}
void DealData()
{
char opt;
Data a,b;
switch(opt=OptStackPop())
{
case '(':
OptStackPush(opt);
break;
case ')':
while((opt=OptStackPop())!='(')
{
OptStackPush(opt);
DealData();
}
break;
case '+':
b=DataStackPop();
a=DataStackPop();
DataStackPush(a+b);
break;
case '-':
b=DataStackPop();
a=DataStackPop();
DataStackPush(a-b);
break;
case '*':
b=DataStackPop();
a=DataStackPop();
DataStackPush(a*b);
break;
case '/':
b=DataStackPop();
a=DataStackPop();
DataStackPush(a/b);
break;
case '!': /*sqrt()*/
a=DataStackPop();
DataStackPush(sqrt(a));
break;
case '#': /*cos()*/
a=DataStackPop();
DataStackPush(cos(a));
break;
case '$': /*sin()*/
a=DataStackPop();
DataStackPush(sin(a));
break;
case '?': /*ln()*/
a=DataStackPop();
DataStackPush(log(a));
break;
case '@': /*tan()*/
a=DataStackPop();
DataStackPush(tan(a));
break;
case ':': /*pow(a,b)*/
b=DataStackPop();
a=DataStackPop();
DataStackPush(pow(a,b));
break;
case ';': /*exp()*/
a=DataStackPop();
DataStackPush(exp(a));
break;
case '&': /*acos()*/
a=DataStackPop();
DataStackPush(acos(a));
break;
case '_': /*asin()*/
a=DataStackPop();
DataStackPush(asin(a));
break;
case '~': /*atan()*/
a=DataStackPop();
DataStackPush(atan(a));
break;
case '^':
b=DataStackPop();
a=DataStackPop();
DataStackPush(log(a)/log(b));
break;
case '>':
a=DataStackPop();
DataStackPush(tan(a));
break;
case '<': /*cot()*/
a=DataStackPop();
DataStackPush(1.0/tan(a));
break;
case '|': /*退出函数 */
ReportErr();
}
}
int OptCmp(char opt1,char opt2)
{
/*比较运算符的优先级*/
int i, j, a=0, b=0;
char opttable[N][M]={{'+','-','\0','\0'},{'*','/','\0','\0'},{'<','>','&','!','#','?','$','@','~','_',':',';','^'},{'(',')','|','\0'}};
for(i=0;i<N;i++)
for(j=0;j<M;j++)
{
if(opt1==opttable[i][j]) a=i;
if(opt2==opttable[i][j]) b=i;
}
return a-b;
}
Operate ChangeOpt(char *opts)
{
/*用字符表示函数运算*/
int len1,len2;
int i, n, yes;
char optstr[]="sqrt!cos#sin$tan@pow:atan~asin_acos&ln?exp;log^tan>cot<exit|";
len1=strlen(opts);
len2=strlen(optstr);
for(i=0;i<len2;i++)
{
yes=1;
for(n=0;n<len1;n++)
if(opts[n]!=optstr[i+n]) yes=0;
if(yes==1)
break;
}
if(yes!=1)
ReportErr(); /*异常退出*/
return optstr[i+n]; /*正常函数返回*/
}
void ReportErr(void)
{
UART0_puts("\nerror!");
}
void GetExpress(char *express)
{
char tmp;
do
{
tmp=UART0_getc();
if ((tmp == 10) || (tmp == 13))
{
tmp = '\n';
}
UART0_putc(tmp);
*express++ = tmp;
}
while (tmp != '\n');
*express = '\0';
}
void AppMain(void * pdata)
{
char exper[100];
Data d;
UART0_SetBuf(100, 100);
UART0_Init(57600, 8, 1, 1);
OptStackInit(OPT_STK_FULL);
DataStackInit(Data_STK_FULL);
UART0_puts("\n======= Genius Calc =======");
for ( ; ; )
{
OptStk.cnt = 0;
OptStk.top = OptStk.base;
DataStk.cnt = 0;
DataStk.top = DataStk.base;
UART0_puts("\nExpression:");
GetExpress(exper);
if (strlen(exper) != 0)
{
d = Calculator(exper);
print_f("\nResult:%f", d);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -