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

📄 ccalc.cpp

📁 CCALC provides convenient way to for performing calculations. You can use standard infix notation f
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//-< CCALC.CPP >-----------------------------------------------------*--------*// Ccalc                      Version 1.02       (c) 1998  GARRET    *     ?  *// (C expression command line calculator)                            *   /\|  *//                                                                   *  /  \  *//                          Created:     20-Oct-98    K.A. Knizhnik  * / [] \ *//                          Last update: 20-Oct-98    K.A. Knizhnik  * GARRET *//-------------------------------------------------------------------*--------*#include <stdio.h>#include <string.h>#include <ctype.h>#include <math.h>#include <errno.h>#include <stdlib.h>#ifdef USE_READLINE#include <readline/readline.h>#include <readline/history.h>#endif#include "ccalc.h"int_t to_int(int_t val) { return val; }double to_float(double val) { return val; }int_t prime(int_t n) {     if (n <= 3) {         return n;    }    n |= 1;     while (true) {        int_t m = (int_t)sqrt((double)n) + 1;        int_t k = 3;        while (true) {             if (k > m) {                 return n;            }            if (n % k == 0) break;            k += 2;        }        n += 2;    }}char* to_bin(int nval, char* pbuf, int nbufsize){    int ncnt;    int bcnt;    int nlen = sizeof(int) * 8 + sizeof(int);    if (pbuf != NULL && nbufsize > nlen)    {        pbuf[nlen] = '\0';        pbuf[nlen - 1] = 'b';        for(ncnt = 0, bcnt = nlen - 2; ncnt < nlen; ncnt ++, bcnt --)        {            if (ncnt > 0 && (ncnt % 8) == 0)            {                pbuf[bcnt] = '.';                bcnt --;            }            pbuf[bcnt] = (nval & (1 << ncnt))? '1' : '0';        }    }    return pbuf;}int_t gcd(int_t x, int_t y) {    while(x) {	int_t r = y%x;	y=x;	x=r;    }    return y;}int_t invmod(int_t x, int_t y) {    int_t m = y;    int_t u = 1, v = 0;    int_t s = 0, t = 1;    while(x) {	int_t q = y/x;	int_t r = y%x;	int_t a = s - q*u;	int_t b = t - q*v;	y=x; s=u; t=v;	x=r; u=a; v=b;    }    if(y!=1) return 0;    while(s<0) s+=m;    return s;}const char* help = "\Input for this calculator are normal C expressions containing operators, float\n\or integer constants, variables and and references to previous results ($n).\n\Precedence and semantic of operators is the same as in C language. There are\n\two extra binary operators: >>> unsigned shift right and ** raising to power.\n\Calculator supports standard set of functions from C mathematics library and\n\also defines function prime(n) for the smallest prime number >= n, gcd(n,m) for\the greatest common divisor of n and m, and invmod(n,m) for inverse of n modulo m.\n\Operators:\n\        ++ -- ! ~ unary + -\n\        **\n\        * / %\n\        + -\n\        << >> >>>\n\        < <= > >= \n\        == != \n\        &\n\        ^\n\        |\n\        = += -= *= /= %= <<= >>= >>>= &= |= ^= **= \n\Functions:\n\        abs\t atan\t cosh\t float\t prime\t sqrt\n\        acos\t atan2\t exp\t log\t sin\t tan\n\        asin\t cos\t int\t log10\t sinh\t tanh\n\        gcd\t invmod\n\Type \"exit\" or \"quit\" to terminate program, \"help\" or \"?\" to show this help\n";int main(int argc, char* argv[]) {     calculator ccalc;    symbol* sp;    symbol::add(FFUNC1, "abs", (void*)(double(*)(double))fabs);    symbol::add(FFUNC1, "acos", (void*)(double(*)(double))acos);    symbol::add(FFUNC1, "asin", (void*)(double(*)(double))asin);    symbol::add(FFUNC1, "atan", (void*)(double(*)(double))atan);    symbol::add(FFUNC2, "atan2", (void*)(double(*)(double,double))atan2);    symbol::add(FFUNC1, "cos", (void*)(double(*)(double))cos);    symbol::add(FFUNC1, "cosh", (void*)(double(*)(double))cosh);    symbol::add(FFUNC1, "exp", (void*)(double(*)(double))exp);    symbol::add(FFUNC1, "log", (void*)(double(*)(double))log);    symbol::add(FFUNC1, "log10", (void*)(double(*)(double))log10);    symbol::add(FFUNC1, "sin", (void*)(double(*)(double))sin);    symbol::add(FFUNC1, "sinh", (void*)(double(*)(double))sinh);    symbol::add(FFUNC1, "tan", (void*)(double(*)(double))tan);    symbol::add(FFUNC1, "tanh", (void*)(double(*)(double))tanh);    symbol::add(FFUNC1, "sqrt", (void*)(double(*)(double))sqrt);    symbol::add(FFUNC1, "float", (void*)to_float);    symbol::add(IFUNC1, "int", (void*)to_int);    symbol::add(IFUNC2, "gcd", (void*)(int_t(*)(int_t,int_t))gcd);    symbol::add(IFUNC2, "invmod", (void*)(int_t(*)(int_t,int_t))invmod);    symbol::add(IFUNC1, "prime", (void*)prime);    sp = symbol::add(VARIABLE, "pi");    sp->val.tag = FLOAT;    sp->val.fval = 3.1415926535897932385E0;    sp = symbol::add(VARIABLE, "e");    sp->val.tag = FLOAT;    sp->val.fval = 2.7182818284590452354E0;    if (argc > 1) {        for (int i = 1; i < argc; i++) {             ccalc.evaluate(argv[i]);        }    } else { #ifndef USE_READLINE        char buf[max_expression_length];#endif        char *p_buf = NULL;        printf("C expression command line calculator.  Author: http://www.garret.ru/~knizhnik\nType \"help\" for more information\n\n");        do {#ifndef USE_READLINE            printf(prompt);            p_buf = fgets(buf, sizeof buf, stdin);#else            p_buf = readline(prompt);#endif            if (p_buf != NULL)            {                if (strncmp(p_buf, "help", 4) == 0 || strncmp(p_buf, "HELP", 4) == 0                         || *p_buf == '?')                {                    printf(help);                } else if (strncmp(p_buf,"exit",4)==0 || strncmp(p_buf,"EXIT",4)==0 ||                        strncmp(p_buf,"quit",4)==0 || strncmp(p_buf,"QUIT",4)==0)                 {                    return 0;                } else if (*p_buf != '\x0') {         #ifdef USE_READLINE                    add_history(p_buf);#endif                    ccalc.evaluate(p_buf);                }#ifdef USE_READLINE                free(p_buf);#endif            }        } while (p_buf != NULL);    }    return 0;}inline unsigned string_hash_function(char* p) {     unsigned h = 0, g;    while(*p) {         h = (h << 4) + *p++;        if ((g = h & 0xF0000000) != 0) {             h ^= g >> 24;        }        h &= ~g;    }    return h;}symbol* symbol::hash_table[hash_table_size];symbol* symbol::add(t_symbol tag, char* name, void* func) {     unsigned h = string_hash_function(name) % hash_table_size;    symbol* sp;    for (sp = hash_table[h]; sp != NULL; sp = sp->next) {         if (strcmp(sp->name, name) == 0) {             return sp;        }    }    sp = new symbol;    sp->tag = tag;    sp->func = func;    sp->name = strdup(name);    sp->val.tag = INT;    sp->val.ival = 0;    sp->next = hash_table[h];    hash_table[h] = sp;    return sp;}   void calculator::error(int pos, char* msg) {     pos += strlen(prompt);    if (pos < 80) {         while (--pos >= 0) putc('.', stderr);        fprintf(stderr, "^\n");    }    fprintf(stderr, "Error: %s\n\n", msg);}t_operator calculator::scan(bool operand){    char name[max_expression_length], *np;    while (isspace(buf[pos])) pos += 1;    switch (buf[pos++]) {       case '\0':        return END;      case '(':        return LPAR;      case ')':        return RPAR;      case '+':        if (buf[pos] == '+') {             pos += 1;            return operand ? PREINC : POSTINC;        } else if (buf[pos] == '=') {             pos += 1;            return SETADD;        }        return operand ? PLUS : ADD;      case '-':        if (buf[pos] == '-') {             pos += 1;            return operand ? PREDEC : POSTDEC;        } else if (buf[pos] == '=') {             pos += 1;            return SETSUB;        }        return operand ? MINUS : SUB;      case '!':        if (buf[pos] == '=') {             pos += 1;            return NE;        }        return NOT;      case '~':        return COM;      case '*':        if (buf[pos] == '*') {             if (buf[pos+1] == '=') {                 pos += 2;                return SETPOW;            }            pos += 1;            return POW;        } else if (buf[pos] == '=') {             pos += 1;            return SETMUL;        }         return MUL;      case '/':        if (buf[pos] == '=') {             pos += 1;            return SETDIV;        }        return DIV;      case '%':        if (buf[pos] == '=') {             pos += 1;            return SETMOD;        }        return MOD;      case '<':        if (buf[pos] == '<') {             if (buf[pos+1] == '=') {                 pos += 2;                return SETASL;            } else {                 pos += 1;                return ASL;            }        } else if (buf[pos] == '=') {             pos += 1;            return LE;        }         return LT;      case '>':        if (buf[pos] == '>') {             if (buf[pos+1] == '>') {                 if (buf[pos+2] == '=') {                     pos += 3;                    return SETLSR;                }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -