本帖最后由 happy886rr 于 2017-1-28 15:21 编辑
[version 3.0] 2017-01-28,更新只更新源码,而不做下载更新,请编译源码获取最新版。
逆波兰计算器revpolish 3.0版,支持复杂多函数混合嵌套。恐怖的计算速度,四则运算每秒可以处理1000万行,复杂数学函数嵌套,每秒可处理200万行。支持最全面的数学函数,支持超长算式,可以自定义#define STACK_SIZE 的值,理论上不限制算式长度。拥有详细的错误反馈,无论是除数为0,还是负数开方,都会立刻终止程序并打印错误信息。跳转排序亦根据使用频率设定,使其以最小的内存、cpu占用、最快的速度完成艰巨的科学计算。
revpolish采取多版本发行策略,请下载支持您设备的版本。
摘要:
x86&x64架构windows版, 下载:revpolish.exe

x86&x64架构linux版, 下载: revpolish

安卓apk 版, 下载: revpolish.apk

arm架构版, 下载: revpolish
用法:
-----------------------------------------------------------------------------
revpolish [expression]
-----------------------------------------------------------------------------
示例:
-----------------------------------------------------------------------------
revpolish ((3*3+2)%6+7.187)*5-7/189+3^2
revpolish (ceil(sin(pi/3)+2)%6+0.187)*e-lg(6.5)
revpolish 5*(arctan(cos(sin(ln(lg(2.71828))))))
-----------------------------------------------------------------------------
备注:
-----------------------------------------------------------------------------
常数类
pi 3.1415926535897932
e 2.7182818284590452
通用类
rand 随机数
round 四舍五入
int 取整
ceil 向上舍入
floor 向下舍入
abs 绝对值
sqrt 开方
lg 常用对数,以10为底
ln 自然对数
exp e的次幂
gamma 伽玛函数
deg 度转弧度
+ 加
- 减
* 乘
/ 除
% 取余数
^ 次方
! 阶乘
三角函数类
sin、cos、tan
arcsin、arccos、arctan
双曲函数类
sinh、cosh、tanh
arcsinh、arccosh、arctanh
-----------------------------------------------------------------------------
revpolish.c 3.0版本源码 | | | | | | | | | | | | | #include <stdio.h> | | #include <stdlib.h> | | #include <math.h> | | | | | | | | #define STACK_SIZE 1024 | | | | #define HELPINFORMATION "\ | | REVERSE POLISH EXPRESSION CALCULATOR,COPYRIGHT@2017~2019 BY HAPPY\n\ | | -----------------------------------------------------------------\n\ | | revpolish [expression]\n\ | | -----------------------------------------------------------------\n\ | | FUNCTIONS:\n\ | | pi=3.1415926535897932, e=2.7182818284590452\n\ | | +, -, *, /, %, ^, !\n\ | | round, floor, ceil, exp, deg, sqrt, abs, lg, ln\n\ | | sin, cos, tan, arcsin, arccos, arctan\n\ | | sinh, cosh, tanh, arcsinh, arccosh, arctanh\n\ | | -----------------------------------------------------------------\n\ | | VERSION 3.0 2017-01-28\n" | | | | | | | | static const char* KEY_WORDS[]={"e", "pi", "sqrt", "lg", "ln", "sin", "cos", "tan", "arcsin", "arccos", "arctan", "deg", "abs", "round", "floor", "ceil", "exp", "sinh", "cosh", "tanh", "arcsinh", "arccosh", "arctanh", "int", "gamma", "rand", NULL}; | | | | char STACK1[STACK_SIZE]={0}; | | | | char STACK2[STACK_SIZE]={0}; | | | | double STACK3[STACK_SIZE]={0}; | | | | | | | | long long fact(long long n) | | { | | return (n<2) ?1 :n*(fact(n-1)); | | } | | | | double RevPolishCore(const char* expression) | | { | | char *op=(char*)expression, *S1=STACK1, *S2=STACK2, **key, *cp, *kp; | | double *S3=STACK3, di, ni; | | int brackets=0; | | STACK3[0]=0; | | | | | | while(*op!='\0'){ | | switch(*op){ | | case ' ' : | | case '\t': | | case '\r': | | case '\n': | | | | op++; | | continue; | | | | case 'a': | | case 'b': | | case 'c': | | case 'd': | | case 'e': | | case 'f': | | case 'g': | | case 'h': | | case 'i': | | case 'j': | | case 'k': | | case 'l': | | case 'm': | | case 'n': | | case 'o': | | case 'p': | | case 'q': | | case 'r': | | case 's': | | case 't': | | case 'u': | | case 'v': | | case 'w': | | case 'x': | | case 'y': | | case 'z': | | | | key=(char**)KEY_WORDS; | | while(*key !=NULL){ | | cp=op, kp=*key; | | | | while(*cp==*kp && *kp!='\0'){ | | cp++, kp++; | | } | | | | if((*cp<'a'||*cp>'z') && (*kp=='\0')){ | | op=cp; | | break; | | } | | key++; | | } | | | | if(*key !=NULL){ | | *(S2++)='.'; | | *(S2++)=' '; | | | | while('A'<=(*S1) && (*S1)<='Z'){ | | *(S2++)=*(S1--); | | } | | *(++S1)=key-(char**)KEY_WORDS+65; | | continue; | | }else{ | | | | fputs("Unrecognized math function\n", stderr); | | exit(1); | | } | | break; | | | | case '(': | | brackets++; | | *(++S1)=*op; | | if(*(op+1)=='-' || *(op+1)=='+'){ | | *(S2++)='0', *(S2++)=' '; | | } | | break; | | | | case ')': | | brackets--; | | while(*S1!='(') | | { | | *(S2++)=*(S1--); | | } | | | | S1--; | | break; | | | | case '+': | | case '-': | | while(S1!=STACK1 && *S1!='(') | | { | | *(S2++)=*(S1--); | | } | | *(++S1)=*op; | | break; | | | | case '^': | | | | while('A'<=(*S1) && (*S1)<='Z') | | { | | *(S2++)=*(S1--); | | } | | *(++S1)=*op; | | break; | | | | case '!': | | | | *(S2++)=*op; | | break; | | | | case '%': | | case '*': | | case '/': | | while(('A'<=(*S1) && (*S1)<='Z') ||*S1=='%' ||*S1=='*' ||*S1=='/' ||*S1=='^'){ | | *(S2++)=*(S1--); | | } | | *(++S1)=*op; | | break; | | | | default : | | if((*op<'0' || *op>'9') && (*op!='.')){ | | | | fputs("Unrecognized operator\n", stderr); | | exit(1); | | } | | | | while(('0'<=*op && *op<='9') ||*op=='.'){ | | *(S2++)=*(op++); | | } | | op--; | | *(S2++)=' '; | | break; | | } | | op++; | | } | | | | | | if(brackets){ | | fputs("The brackets '(' or ')' are not closed", stderr); | | exit(1); | | } | | | | | | while(S1 !=STACK1){*(S2++)=*(S1--);} | | *S2=' '; | | | | | | op=STACK2; | | while(*op!=' '){ | | switch(*op){ | | case 'A': | | *S3=2.7182818284590452; | | break; | | case 'B': | | *S3=3.1415926535897932; | | break; | | case 'C': | | if(*S3 <0){ | | | | fputs("Negative numbers have no square root\n", stderr); | | exit(1); | | } | | *(S3-1)=sqrt(*S3); | | S3--; | | break; | | case 'D': | | if(*S3 <0){ | | | | fputs("Negative numbers are not logarithmic\n", stderr); | | exit(1); | | } | | *(S3-1)=log10(*S3); | | S3--; | | break; | | case 'E': | | if(*S3 <0){ | | | | fputs("Negative numbers have no natural logarithms\n", stderr); | | exit(1); | | } | | *(S3-1)=log(*S3); | | S3--; | | break; | | case 'F': | | *(S3-1)=sin(*S3); | | S3--; | | break; | | case 'G': | | *(S3-1)=cos(*S3); | | S3--; | | break; | | case 'H': | | if(*S3==3.1415926535897932/2){ | | | | fputs("The pi/2 has no tangent\n", stderr); | | exit(1); | | } | | *(S3-1)=tan(*S3); | | S3--; | | break; | | case 'I': | | *(S3-1)=asin(*S3); | | S3--; | | break; | | case 'J': | | *(S3-1)=acos(*S3); | | S3--; | | break; | | case 'K': | | *(S3-1)=atan(*S3); | | S3--; | | break; | | case 'L': | | *(S3-1)=(*S3)*3.1415926535897932/180.0; | | S3--; | | break; | | case 'M': | | *(S3-1)=fabs(*S3); | | S3--; | | break; | | case 'N': | | *(S3-1)=round(*S3); | | S3--; | | break; | | case 'O': | | *(S3-1)=floor(*S3); | | S3--; | | break; | | case 'P': | | *(S3-1)=ceil(*S3); | | S3--; | | break; | | case 'Q': | | *(S3-1)=exp(*S3); | | S3--; | | break; | | case 'R': | | *(S3-1)=sinh(*S3); | | S3--; | | break; | | case 'S': | | *(S3-1)=cosh(*S3); | | S3--; | | break; | | case 'T': | | *(S3-1)=tanh(*S3); | | S3--; | | break; | | case 'U': | | *(S3-1)=asinh(*S3); | | S3--; | | break; | | case 'V': | | *(S3-1)=acosh(*S3); | | S3--; | | break; | | case 'W': | | *(S3-1)=atanh(*S3); | | S3--; | | break; | | case 'X': | | *(S3-1)=(int)(*S3); | | S3--; | | break; | | case 'Y': | | if(*S3 <0){ | | | | fputs("Negative numbers have no factorial", stderr); | | exit(1); | | } | | *(S3-1)=tgamma((*S3)+1); | | S3--; | | break; | | case 'Z': | | | | if(*S3 <0){ | | | | fputs("A negative number can not be used as a random upper bound", stderr); | | exit(1); | | }else if(*S3 <2){ | | | | *(S3-1)=rand() % 8192 /8192.0; | | }else{ | | *(S3-1)=rand() % (int)(*S3); | | } | | S3--; | | break; | | case '+': | | *(S3-1)+=*S3; | | S3--; | | break; | | case '-': | | *(S3-1)-=*S3; | | S3--; | | break; | | case '*': | | *(S3-1)*=*S3; | | S3--; | | break; | | case '%': | | case '/': | | if(*S3 !=0){ | | if(*op=='%'){ | | | | *(S3-1)=(int)*(S3-1) % (int)*S3; | | }else{ | | *(S3-1)/=*S3; | | } | | | | }else{ | | | | fputs("Divisor is zero error\n", stderr); | | exit(1); | | } | | S3--; | | break; | | case '^': | | if(*(S3-1)==0 && *S3<0){ | | | | fputs("Function pow's divisor is zero error\n", stderr); | | exit(1); | | } | | *(S3-1)=pow(*(S3-1), *S3); | | S3--; | | break; | | case '!': | | if(*S3 <0){ | | | | fputs("Negative numbers have no factorial\n", stderr); | | exit(1); | | } | | *S3=fact((long long)(*S3)); | | break; | | default : | | | | di=0, ni=1; | | while('0'<=*op && *op<='9'){ | | di=10*di+(*op)-'0'; | | op++; | | } | | if(*op=='.'){ | | op++; | | while('0'<=*op && *op<='9'){ | | di=10*di+(*op)-'0'; | | op++, ni*=10; | | } | | } | | *(++S3)=di/ni; | | break; | | } | | op++; | | } | | | | | | if(isinf(*S3)||isnan(*S3)){ | | fputs("Overflow or illegal operation is calculated", stderr); | | exit(1); | | } | | | | | | | | | | | | | | fprintf(stdout, "ORIGINALEXP: %s\n", expression); | | | | | | fprintf(stdout, "REVPOLISH: "); | | op=STACK2; | | while(op!=S2){ | | if(*op=='.' && *(op+1)==' '){ | | op++; | | | | }else if('A'<=(*op) && (*op)<='Z'){ | | fprintf(stdout, "%s ", KEY_WORDS[*op-65]); | | | | }else{ | | fputc(*op, stdout); | | if(*op=='+' ||*op=='-' ||*op=='*' ||*op=='/' ||*op=='%' ||*op=='^' ||*op=='!'){fputc(' ', stdout);} | | } | | op++; | | } | | fputc('\n', stdout); | | | | | | fprintf(stdout, "RESULT: %.16lf\n", *S3); | | } | | | | | | int main(int argc, char** argv) | | { | | if((argc==1) || (argc==2 && argv[1][0]=='/' && (argv[1][1]=='?'||argv[1][1]=='h'))){ | | | | fputs(HELPINFORMATION, stderr); | | exit(1); | | } | | | | srand((int)getpid()); | | RevPolishCore(argv[1]); | | return 0; | | }COPY |
gcc编译参数gcc revpolish.c -std=gnu99 -O3 -s -o revpolish.exeCOPY cmd调用示例 | @echo off | | ::**************************************************** | | :HEAD | | revpolish | | ping -n 2 127.1>NUL | | echo; | | echo; | | | | ::**************************************************** | | :TEST | | for /f "delims=" %%a in ('more +16 "%~f0"') do ( | | revpolish "%%a"&echo; | | ) | | set/p=Well Done!&exit | | | | ::**************************************************** | | abs(1/(2*50)*lg(2*pi*(e^2)/(2*50+1))-lg2) | | ((((((((2^2)*2)^2)*2)^2)*2)^2)^2)*2 | | -((((((((2^2)*2)^2)*2)^2)*2)^2)^2)*2 | | 23+56/(102-100)*((36-24)/(8-6)) | | sin(6)+3 | | cos(sin(6)^4)^6 | | cos(sin(-6)^4)^6 | | cos(-sin(6)^4)^6 | | 2^cos(sin(6)^4)^6 | | 2^sin(3)^2 | | 4^4! | | 3^4^2 | | gamma(20.3)COPY |
|