1999년 12월 3일 금요일

Calculator 계산기

간단하게 사용할 수 있는 계산기. Visual C++ (MFC) 로 만들었다.
괄호 () 를 이용한 우선순위 변경과 몇가지 수학함수 (abs, acos, asin, atan, ceil, cos, cosh, exp, floor, ln, log, pi, sin, sinh, sqr, tan, tanh) 를 사용할 수 있다.



CalcLib.cpp

#include <math.h>
#include <string.h>

#define _PI_ 3.14159265359

enum CALCCLASS_TYPE {ADD, SUB, MUL, DEV, OPEN, CLOSE, NUM, STRING, EXP, END, _ERROR_};

class Ccalcclass {
    public:
        // if (_DegRad_) degree else radian.
        double calc (char *s, int _DegRad_);

    private:
        void lex ();
        double A ();
        double B ();
        double C ();
        double D ();
        double E ();
        double S ();

        char *data;
        int p;
        int type;
        double num;
        char str[10];
        int DegRad;
};

void Ccalcclass::lex () {
    double point;
    int i;

    while (data[p] == ' ') p++;

    if (data[p] == '+') type = ADD;
    else
    if (data[p] == '-') type = SUB;
    else
    if (data[p] == '*') type = MUL;
    else
    if (data[p] == '/') type = DEV;
    else
    if (data[p] == '(') type = OPEN;
    else
    if (data[p] == ')') type = CLOSE;
    else
    if (data[p] == '^') type = EXP;
    else
    if ((('0' <= data[p]) && (data[p] <= '9')) || (data[p] == '.')) {
        type = NUM;
        num = 0;
        point = 0.0;
        while ((('0' <= data[p]) && (data[p] <= '9')) || (data[p] == '.')) {
            if (data[p] != '.') {
                if (point == 0.0) num = num*10 + (data[p] - '0');
                else {
                    num = num + point * (data[p] - '0');
                    point = point * 0.1;
                }
            } else
            if (point == 0) point = 0.1;
            else {
                type = _ERROR_;
                return;
            }
            p++;
        }
        return;
    } else
    if (('a' <= data[p]) && (data[p] <= 'z')) {
        type = STRING;
        i = 0;
        while (('a' <= data[p]) && (data[p] <= 'z') && i<9) {
            str[i++] = data[p++];
        }
        str[i] = 0;
        return;
    } else
        if (data[p] == 0) type = END;
    else
        type = _ERROR_;

    p++;
}

double Ccalcclass::A () {
    double rv;

    rv = B ();
    while ((type == ADD) || (type == SUB)) {
        if (type == ADD) {
            lex ();
            rv = rv + B ();
        } else
        if (type == SUB) {
           lex ();
           rv = rv - B ();
        }
    }
    return rv;
}

double Ccalcclass::B () {
    double rv;

    rv = C ();
    while ((type == MUL) || (type == DEV)) {
        if (type == MUL) {
            lex ();
           rv = rv * C ();
        } else
        if (type == DEV) {
           lex ();
            rv = rv / C ();
        }
    }
    return rv;
}

double Ccalcclass::C () {
    double rv;

    if (type == SUB) {
        lex ();
        rv = 0.0 - D ();
    } else
        rv = D ();
    return rv;
}

double Ccalcclass::D () {
    double rv;

    rv = E ();
    while (type == EXP) {
       lex ();
       rv = pow (rv, E());
    }
    return rv;
}

double Ccalcclass::E () {
    double rv;

    if (type == OPEN) {
        lex ();
        rv = A ();
        if (type == CLOSE) lex ();
        else type = _ERROR_;
    } else
    if (type == NUM) {
        rv = num;
        lex ();
    } else
    if (type == STRING) rv = S ();
    else
        type = _ERROR_;
    return rv;
}

double Ccalcclass::S () {
    double rv;

    if (stricmp (str, "abs") == 0) {
        lex ();
        rv = fabs (C ());
    } else
    if (stricmp (str, "acos") == 0) {
        lex ();
        if (DegRad) rv = acos (C ())/_PI_*180;
        else rv = acos (C ());
    } else
    if (stricmp (str, "asin") == 0) {
        lex ();
        if (DegRad) rv = asin (C ())/_PI_*180;
        else rv = asin (C ());
    } else
    if (stricmp (str, "atan") == 0) {
        lex ();
        if (DegRad) rv = atan (C ())/_PI_*180;
        else rv = atan (C ());
    } else
    if (stricmp (str, "ceil") == 0) {
        lex ();
        rv = ceil (C ());
    } else
    if (stricmp (str, "cos") == 0) {
        lex ();
        if (DegRad) rv = cos (C ()*_PI_/180);
        else rv = cos (C ());
    } else
    if (stricmp (str, "cosh") == 0) {
        lex ();
        rv = cosh (C ());
    } else
    if (stricmp (str, "exp") == 0) {
        lex ();
        rv = exp (C ());
    } else
    if (stricmp (str, "floor") == 0) {
        lex ();
        rv = floor (C ());
    } else
    if (stricmp (str, "ln") == 0) {
        lex ();
        rv = log (C ());
    } else
    if (stricmp (str, "log") == 0) {
        lex ();
        rv = log10 (C ());
    } else
    if (stricmp (str, "pi") == 0) {
        lex ();
        rv = _PI_;
    } else
    if (stricmp (str, "sin") == 0) {
        lex ();
        if (DegRad) rv = sin (C ()*_PI_/180);
        else rv = sin (C ());
    } else
    if (stricmp (str, "sinh") == 0) {
        lex ();
        rv = sinh (C ());
    } else
    if (stricmp (str, "sqr") == 0) {
        lex ();
        rv = sqrt (C ());
    } else
    if (stricmp (str, "tan") == 0) {
        lex ();
        if (DegRad) rv = tan (C ()*_PI_/180);
        else rv = tan (C ());
    } else
    if (stricmp (str, "tanh") == 0) {
        lex ();
        rv = tanh (C ());
    } else
        type = _ERROR_;
    return rv;
}

double Ccalcclass::calc (char *s, int _DegRad_) {
    double rv;

    data = s;
    DegRad = _DegRad_;

    p = 0;
    lex ();
    rv = A ();
    if (type != END) s[0] = 0;
    return rv;
}

double calc (char *s, int DegRad) {
    static Ccalcclass calcclass;
    return calcclass.calc (s, DegRad);
}

1999년 1월 1일 금요일

같은것 찾기

같은것 찾기. 블럭을 클릭하면 크기가 6인 임시 저장소로 내려가고, 임시 저장소에 같은블럭이 3개가 차면 사라진다. 임시저장소가 꽉 차면 게임종료. 10판까지 있다.