⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calc.c

📁 Rabbit 32Bit RTOS源代码
💻 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 + -