www.pudn.com > cwin.rar > EXP.C


    /*----------------------------------------------------------- 
        程序模块 Exp.c : 表达式处理 
    -----------------------------------------------------------*/ 
    #include  
    #include  
    #include  
 
    /*-- 函数代码定义 -------------------------*/ 
    #define ABS        288 
    #define SQR      12563 
    #define EXP      22512 
    #define POW      32608 
    #define LG       13824 
    #define LN       15616 
    #define SIN      10448 
    #define COS      12064 
    #define TAN      12496 
    #define ATAN      4877 
    #define MAX      16752 
    #define MIN      18640 
    #define INT       3376 
    #define ROUND     8013 
    #define MOD      20016 
    #define HEX      30064 
 
    /*-- 全局变量定义 -------------------------*/ 
    extern int _ErrorNo; 
    int        _ResultType='N'; 
    char       _ResultString[21]; 
 
    /*-- 静态变量定义 -------------------------*/ 
    static unsigned char *_Token = NULL; 
 
    /*-- 内部函数说明 -------------------------*/ 
    static int    _Cdecl func_code (char *fun_name); 
    static double _Cdecl arith     (int op,double n1,double n2); 
    static int    _Cdecl skip_space(void); 
    static double _Cdecl htof      (char *s); 
    static double _Cdecl primitive (void); 
    static double _Cdecl level5    (void); 
    static double _Cdecl level6    (void); 
    static double _Cdecl level7    (void); 
    static double _Cdecl level9    (void); 
 
    /*----------------------------------------------------------- 
        函数 expression : 表达式处理 
    -----------------------------------------------------------*/ 
    double _Cdecl expression(string) 
    char *string;                      /* 待处理的表达式字符串 */ 
    { 
        double result; 
 
        _ResultType = 'N'; 
        _ErrorNo    = 0; 
        _Token      = string; 
        skip_space(); 
        if(_Token==NULL || *_Token==0) 
            _ErrorNo=201; 
        result      = level5(); 
        if(*_Token && _ErrorNo==0) 
            _ErrorNo= 212; 
        if(_ErrorNo==0 && _ResultType=='N') 
            sprintf(_ResultString,"%20.6f",result); 
        return result; 
    } 
 
    /*----------------------------------------------------------- 
        内部函数 level5 : 处理加和减 
    -----------------------------------------------------------*/ 
    static double _Cdecl level5(void) 
    { 
        double r1 = level6(),r2; 
        int op; 
 
        if(_ErrorNo==0) 
            while((op=*_Token)=='+' || op=='-') 
            { 
                _Token++; 
                skip_space(); 
                r2 = level6(); 
                if(_ErrorNo) 
                    break; 
                r1 = arith(op,r1,r2); 
                if(_ErrorNo) 
                    break; 
            } 
        return r1; 
    } 
 
    /*----------------------------------------------------------- 
        内部函数 level6 : 处理乘和除 
    -----------------------------------------------------------*/ 
    static double _Cdecl level6(void) 
    { 
        double r1=level7(),r2; 
        int op; 
 
        if(_ErrorNo==0) 
            while((op=*_Token)=='*' || op=='/') 
            { 
                _Token++; 
                skip_space(); 
                r2 = level7(); 
                if(_ErrorNo) 
                    break; 
                r1 = arith(op,r1,r2); 
                if(_ErrorNo) 
                    break; 
            } 
        return r1; 
    } 
 
    /*----------------------------------------------------------- 
        内部函数 level7 : 处理正负号 
    -----------------------------------------------------------*/ 
    static double _Cdecl level7(void) 
    { 
        double r; 
        int op=*_Token; 
        if(op=='-' || op=='+') 
        { 
            _Token++; 
            skip_space(); 
            r = level9(); 
            if(_ErrorNo==0) 
                r = arith(op,0,r); 
        } 
        else 
            r = level9(); 
        return r; 
    } 
 
    /*----------------------------------------------------------- 
        内部函数 level9 : 处理括号 
    -----------------------------------------------------------*/ 
    static double _Cdecl level9(void) 
    { 
        double r; 
 
        if(*_Token=='(') 
        { 
            _Token++; 
            skip_space(); 
            r = level5(); 
            if(*_Token==')') 
            { 
                _Token++; 
                skip_space(); 
            } 
            else 
                _ErrorNo = 203; 
        } 
        else 
            r = primitive(); 
        return r; 
    } 
 
    /*----------------------------------------------------------- 
        内部函数 primitive : 处理运算对象 
    -----------------------------------------------------------*/ 
    static  double _Cdecl primitive(void) 
    { 
        double r[2]; 
        int op; 
        char tmp[21],*p; 
 
        skip_space(); 
        if(*_Token==0) 
            _ErrorNo = 204; 
 
        /*-- 如果是数字则按数值处理 -----------*/ 
        else if(isdigit(*_Token)) 
        { 
            p = tmp; 
            while(isalnum(*_Token) || *_Token=='.' || *_Token=='H' || *_Token=='h') 
                *p++=*_Token++; 
            *p = 0; 
            if(isdigit(*(_Token-1))) 
                r[0]=atof(tmp); 
            else if(*(_Token-1)=='H' || *(_Token-1)=='h') 
                r[0]=htof(tmp); 
            else 
                _ErrorNo=213; 
        } 
 
        /*-- 如果是字母则按函数名处理 ---------*/ 
        else if(isalpha(*_Token)) 
        { 
            p = tmp; 
            do 
            { 
                *p++=*_Token++; 
            }while(isalpha(*_Token)); 
            *p = 0; 
            strupr(tmp); 
            op = func_code(tmp); 
            skip_space(); 
 
            /*-- 如果有括号则处理参数表 -------*/ 
            if(*_Token=='(') 
            { 
                int i; 
                _Token++; 
                for(i=0;i<2;i++) 
                { 
                    skip_space(); 
                    r[i]=level5(); 
                    if(_ErrorNo) 
                        break; 
                    if(*_Token==',') 
                    { 
                        _Token++; 
                        skip_space(); 
                    } 
                    else 
                        break; 
                } 
                if(_ErrorNo==0) 
                { 
                    if(*_Token!=')') 
                        _ErrorNo=203; 
                    else 
                        _Token++; 
                    skip_space(); 
                } 
                if(_ErrorNo==0) 
                    r[0]=arith(op,r[0],r[1]); 
            } 
 
            /*-- 如果没有参数表则出错 ---------*/ 
            else 
                _ErrorNo=211; 
        } 
        else 
            _ErrorNo=207; 
        skip_space(); 
        return r[0]; 
    } 
 
    /*----------------------------------------------------------- 
        内部函数 skip_space : 跳过表达式中的空格 
    -----------------------------------------------------------*/ 
    static int _Cdecl skip_space(void) 
    { 
        while(isspace(*_Token)) 
            _Token++; 
    } 
 
    /*----------------------------------------------------------- 
        内部函数 arith : 运算 
    -----------------------------------------------------------*/ 
    static double _Cdecl arith(int op,double n1,double n2) 
    { 
        if(op!=HEX && _ResultType=='C') 
        { 
            _ErrorNo=208; 
            return n1; 
        } 
        switch(op) 
        { 
            case '+': 
                n1+=n2; 
                break; 
            case '-': 
                n1-=n2; 
                break; 
            case '*': 
                n1*=n2; 
                break; 
            case '/': 
                n1/=n2; 
                break; 
            case ABS: 
                n1=fabs(n1); 
                break; 
            case SQR: 
                if(n1>=0) 
                    n1=sqrt(n1); 
                else 
                    _ErrorNo=209; 
                break; 
            case EXP: 
                n1=exp(n1); 
                break; 
            case POW: 
                n1=pow(n1,n2); 
                break; 
            case LG: 
                if(n1<=0.0) 
                    _ErrorNo=210; 
                else 
                    n1=log10(n1); 
                break; 
            case LN: 
                if(n1<=0.0) 
                    _ErrorNo=210; 
                else 
                    n1=log(n1); 
                break; 
            case SIN: 
                n1=sin(n1); 
                break; 
            case COS: 
                n1=cos(n1); 
                break; 
            case TAN: 
                n1=tan(n1); 
                break; 
            case ATAN: 
                n1=atan2(n1,n2); 
                break; 
            case MAX: 
                n1=(n1>=n2?n1:n2); 
                break; 
            case MIN: 
                n1=(n1<=n2?n1:n2); 
                break; 
            case INT: 
                { 
                    long tmp=n1; 
                    n1=tmp; 
                } 
                break; 
            case ROUND: 
                { 
                    int i=n2; 
                    n1*=pow(10.0,i); 
                    n2=floor(n1); 
                    if(n1-n2>=0.5) 
                        n2+=1.0; 
                    else if(n1-n2<=-0.5) 
                        n2-=1.0; 
                    n1=n2/pow(10.0,i); 
                } 
                break; 
            case MOD: 
                n1=fmod(n1,n2); 
                break; 
            case HEX: 
                sprintf(_ResultString,"%lXH",(long)(n1)); 
                _ResultType='C'; 
                break; 
            default: 
                _ErrorNo=211; 
        } 
        return n1; 
    } 
 
    /*----------------------------------------------------------- 
        内部函数 func_code : 函数名转换为代码 
    -----------------------------------------------------------*/ 
    static int _Cdecl func_code(char *fun_name) 
    { 
        int code=0,i,len=strlen(fun_name); 
        for(i=0;i<4;i++) 
        { 
            code<<=4; 
            if(i='A' && *s<='F') 
                v=v*16-'A'+10+(*s); 
            else 
                break; 
            s++; 
        } 
        return v*=sign; 
    }