逆波兰计算器revpolish.exe

回复
happy886rr
渐入佳境
渐入佳境
帖子: 45
注册时间: 2016年09月27日 16:11
联系:

逆波兰计算器revpolish.exe

帖子 happy886rr »

纯C语言写的计算器,支持复杂多函数混合嵌套,每秒可连续处理百万行乃至千万行算式。
摘要:
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
通用类
round 四舍五入
floor 整取
abs 绝对值
ceil 向上舍入
deg 角度转弧度
exp e的次幂
sqrt 开方
fac 阶乘
lg 常用对数,以10为底
ln 自然对数
+ 加
- 减
* 乘
/ 除
% 取余数
^ 次方
! 阶乘

三角函数类
sin、cos、tan
arcsin、arccos、arctan

双曲函数类
sinh、cosh、tanh
arcsinh、arccosh、arctanh
-----------------------------------------------------------------------------
revpolish.c源码:
/*
REVERSE POLISH EXPRESSION CALCULATOR, COPYRIGHT@2017~2019 BY HAPPYSXYF
REVPOLISH.EXE
VERSION 1.6
*/

#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <windows.h>

/***************定义宏变量***************/
//堆栈尺寸
#define STACK_SIZE 1024
//帮助说明
#define HELPINFORMATION "\
REVERSE POLISH EXPRESSION CALCULATOR, VERSION 1.6\n\
-----------------------------------------------------------------\n\
revpolish [expression]\n\
-----------------------------------------------------------------\n\
EXAMPLES:\n\
revpolish ((3*3+2)%6+7.187)*5-7/189+3^2\n\
revpolish (ceil(sin(pi/3)+2)%6+0.187)*e-lg(6.5)\n\
revpolish 5*(arctan(cos(sin(ln(lg(2.71828))))))\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\
COPYRIGHT@2017~2019 BY HAPPYSXYF 2017-01-03\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", 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;

//生成逆波兰
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 '(':
*(++S1)=*op;
if(*(op+1)=='-' || *(op+1)=='+'){
*(S2++)='0', *(S2++)=' ';
}
break;

case ')':
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++;
}
//收尾逆波兰
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){
//π/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)=(*S3<0)?(-(*S3)):(*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 '+':
*(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++;
}

/////////////////////////////////////////////////////////////////////
//返回计算结果
//return *S3;

//打印中缀式
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);
}

/*************MAIN主函数入口*************/
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);
}
RevPolishCore(argv[1]);
return 0;
}
回复

在线用户

正浏览此版面之用户: 没有注册用户 和 0 访客