计算器源码~控制台C语言

  • Post author:
  • Post category:其他


/*
>>控制台科学计算器源码
>>部分源码参考c4droid代码手册
>>by:千百度
>>转载请注明来源
>>date:2017.3.20
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
#include <time.h>

//初始化系统常量
#define N 200
#define P M_PI
#define E M_E
#define MAX INT_MAX
#define MIN INT_MIN
#define MIN_XS 0.000001
#define PD jg-(int)jg

//初始化界面文本
const char *S1="--------------------------------------------\n->科学计算器v1.2\n->by 千百度(部分源码参考c4droid代码手册)\n->QQ:736226400\n--------------------------------------------\n\033[47;35m->查看函数说明请输入:hs\n->数据统计模式请输入:tj\n->输入表达式开始计算\n\033[47;34m--------------------------------------------\n\033[47;30m",*S2="\033[47;35m--------------------------------------------\n->三角函数(x为角度):sin(x),cos(x),tan(x)\n->反△函数(值为角度):asin(x),acos(x),atan(x)\n->双曲函数:sinh(x),cosh(x),tanh(x)\n->常用对数和自然对数:lg(x),ln(x)\n->开方函数和e^x:sqrt(x),exp(x)\n->在(0,1)之间产生一个随机小数*x:rand(x)\n->运算符及优先级:()大于%%^ 大于*/大于 +-\n\033[47;31m->特殊规定:\n---->1,负数要加括号除非在第一位例如-5+(-3)\n---->2,函数后为指数应用括号指明优先级例如:\n---->(sin45)^3不加括号系统默认sin(45^3)\n---->3,整数部分超出10位将以科学记数法表示\n---->表达式不允许出现空格\n---->运算结果取值-1.7E-308~1.7*E308\n--------------------------------------------\033[47;30m\n",*S3="\033[47;34m--------------------------------------------\n->统计计算模式说明:\n--------------------------------------------\n\033[47;35m->数据统计函数:tj(x1;x2;...;xn)\n->相关关系函数:gx(x1,y1;x2,y2;...xn,yn)\n->二项分布:pxb(k;n;p)\n->参数要求(n>=k,1=>p>=0)\n->超几何分布:pxh(k;N;M;n)\n->参数要求(N>=M,n>=k,M>=k,N>=n)\n->请注意符号,并严格按照格式输入\n->输入exit退出统计模式\n\033[47;34m--------------------------------------------\033[47;30m\n",*d1 = "abcdefghijklmnopqrstuvwxyz^!();",*d2="1234567890.#";

double FS(void);//数值及括号处理函数
char token[N];  // 存放表达式字符串数组 
char str[N];	//获取输入字符串数组 
int n = 0, m = 0, t = 0,x=0;
int c = 0;  //判断是否已经计算0表示没有

//角度转弧度
double jtoh(double a)
{
	return P*a/180;
}
//弧度转角度
double htoj(double a)
{
	return 180*a/P;
}
//阶乘
double jc(int a)
{
	double b=1;
	if (a)
	{
		for (int i=1;i<=a;i++)
		b*=i;
	}
	return b;
}
//排列
double npr(int a,int b)
{
	if (b<=a)
	return jc(a)/jc(a-b);
	else
	{
		printf("参数有误error\n");
		return -1;
	}
}
//组合
double ncr(int a,int b)
{
	if (b<=a)
	return npr(a,b)/jc(b);
	else
	{
		printf("参数有误error\n");
		return -1;
	}
}

//数据统计
void tj(double a[N][2],int n)
{
printf("\033[47;34m--------------------------------------------\n->数据统计\n--------------------------------------------\n\033[47;31m");
	int i;
	double x=0,s=0;
	for (i=0; i<n;i++)
	{
		printf("x%d=%f\n",i+1,a[i][0],i+1);
		x=x+a[i][0];
	}
	int p=0;
	x=x/n;
	printf("->平均值为:%.3f",x);
	for (p;p<n;p++)
		s=s+(a[p][0]-x)*(a[p][0]-x);
		s=s/n;
	printf("\n->方差为:%.3f",s);
	s=sqrt(s);
	printf("\n->标准差为:%.3f\n元素个数n=%d\n\033[47;30m",s,n);
}

 //变量间相关关系 回归方程
void gx(double a[N][2],int n)
 {
 int i;
double s1=0,x=0,y=0;
double c,b,s2=0,s3=0,r;	printf("\033[47;34m--------------------------------------------\n->变量相关关系分析\n--------------------------------------------\033[47;31m\n");
	for (i=0;i<n;i++)
	{
		printf("->x%d=%f->y%d=%f\n",i+1,a[i][0],i+1,a[i][1]);
//		printf("%f>>%f\n",a[i][0],a[i][1]);
		s1=s1+a[i][0]*a[i][1];
		s2=s2+a[i][0]*a[i][0];
		s3=s3+a[i][1]*a[i][1];
		x=x+a[i][0];y=y+a[i][1];
	}
	x=x/n;y=y/n;
	s1=s1-x*y*n;
	s2=s2-n*x*x;
	s3=s3-n*y*y;
	b=s1/s2;
	c=y-b*x;
	printf("->回归方程:y=%.3fx+%.3f",b,c);
	r=s2*s3;
	r=s1/sqrt(r);
	printf("\n->相关系数r=%f",r);
	if (r<-0.75)
	printf("\n->负相关关系很强");
	else
	if (r>0.75)
	printf("\n->正相关关系很强");
	else
	if (-0.75<r&&r<-0.3||0.3<r&&r<0.75)
	printf("\n->相关性一般");
	else
	if (-0.3<r&&r<0.3)
	printf("\n->相关性较弱");
	else
	printf("\n->参数错误!");
	printf("\n->元素个数n=%d\n",n);
}
//二项分布求期望方差
void pxb(double a[N][2])
{
	int k=(int)a[0][0];
	int n=(int)a[1][0];
	double p=a[2][0];
	if (n>=k&&p>=0&&p<=1)
	{
	printf("\033[47;31m--------------------------------------------\n数学期望EX=%f\n",n*p);
	printf("方差DX=%f\n",n*p*(1-p));
	printf("在%d次独立重复试验中,事件A发生%d次的概率p=%f\n",n,k,ncr(n,k)*pow(p,k)*pow(1-p,n-k));
	}
	else
		printf("\033[47;31m--------------------------------------------\n->参数要求\n->n不小于k\n->p的取值范围[0,1]\n->error\n--------------------------------------------\n\033[47;30m");
}
//超几何分布
void pxh(double a[N][2])
{
	int k=(int)a[0][0];
	int n=(int)a[1][0];
	int m=(int)a[2][0];
	int n1=(int)a[3][0];
	if (n>=n1&&m>=k&&n1>=k&&n>=m)
	{
	printf("\033[47;31m--------------------------------------------\n数学期望EX=%f\n",((double)n1)*((double)m)/((double)n));
	printf("方差DX=%f\n",n1*m*(n-m)*(n-n1)/(pow(n,2)*(n-1)));
	printf("产品总数N=%d\n含有次品数M=%d\n不放回抽取件数n=%d\n其中含X件次品\n则事件{X=%d}发生的概率p(X=%d)=%f\n\033[47;30m",n,m,n1,k,k,ncr(m,k)*ncr(n-m,n1-k)/ncr(n,n1));
	}
	else
	{
		printf("\033[47;34m--------------------------------------------\n->参数要求\n->N不小于M\n->n不小于k\n->M不小于k\n->N不小于n\nerror\n--------------------------------------------\n\033[47;30m");
	}
}
//产生0~1之间的浮点随机数
double rand0(void)
{
	 /* 初始化伪随机数生成器 */    
    srand((unsigned int)time(NULL));
    return (double)rand() / RAND_MAX;
}
/*统计,概率,计算*/
void math_hs(char *str)
{
	char str0[N],*s,*s0;
	char*p[N];
	double x[N][2],d=0;
	int i=0,n=0,j=0;
	strcpy(str0,str);
	s0 = strtok(str0,d2);
	p[i] = strtok(str, d1);
    while ((s = strtok(NULL, d1)))
    {
    	i++;
    	n=i+1;
    	p[i] = s;
    	//printf(">>%s\n",p[i]);
   }
   for (j=0;j<=i;j++)
   {
   	if(strchr(p[j],','))
   	{
   		x[j][0]=atof(strtok(p[j],","));
   		x[j][1]=atof(strtok(NULL,","));
   	}
   	else
   	    x[j][0]=atof(p[j]);
   }
   
   if (strstr(s0,"tj"))
   	tj(x,n);
   if (strstr(s0,"gx"))
   	gx(x,n);
   if (strstr(s0,"pxb"))
   pxb(x);
   if (strstr(s0,"pxh"))
   pxh(x);
   if (strstr(s0,"rand"))
   printf("在0~1之间产生一个随机小数:%f\n",rand0());
   
}
//处理三角函数,对数,指数,阶乘等
double HS(void)
{
	char a[5]={0x00};
	int i=0;
	double acting = FS(),act=0;
	while (isalpha(token[m])||token[m]=='^'||token[m]=='!'||token[m]=='%')
	{
		a[i++]=str[t-1];
		switch (token[m])
		{
			case '^':
			token[++m] = str[t++];
			act=FS();
			printf("步骤%d: %g^%g",++x,acting,act);
			acting=pow(acting,act);
			break;
			case '!':
			token[++m] = str[t++];
			printf("步骤%d: %g的阶乘",++x,acting);
			acting=jc(acting);
			FS();
			break;
			case '%':
			token[++m] = str[t++];
			printf("步骤%d: %g%",++x,acting);
			acting/=100;
			FS();
			break;
			case 'C':
			token[++m] = str[t++];
			act=FS();
			printf("步骤%d: 组合%gC%g",++x,acting,act);
			acting=ncr(acting,act);
			break;
			case 'P':
			token[++m] = str[t++];
			act=FS();
			printf("步骤%d: 排列%gP%g",++x,acting,act);
			acting=npr(acting,act);
			break;
			default:
			token[++m] = str[t++];
			break;
		}
	}
	//三角函数
	if (islower(a[0]))
	{
		act=FS();
		printf("步骤%d: %s(%g)",++x,a,act);
	}
	if(strstr(a,"sin")&&a[0]!='a'&&a[3]!='h')
	acting=sin(jtoh(act));
	if(strstr(a,"cos")&&a[0]!='a'&&a[3]!='h')
	acting=cos(jtoh(act));
	if(strstr(a,"tan")&&a[0]!='a'&&a[3]!='h')
	acting=tan(jtoh(act));
	//反三角函数
	if(strstr(a,"asin"))
	acting=htoj(asin(act));
	if(strstr(a,"acos"))
	acting=htoj(acos(act));
	if(strstr(a,"atan"))
	acting=htoj(atan(act));
	//双曲函数
	if(strstr(a,"sinh"))
	acting=sinh(act);
	if(strstr(a,"cosh"))
	acting=cosh(act);
	if(strstr(a,"tanh"))
	acting=tanh(act);
	//对数函数
	if(strstr(a,"lg"))
	acting=log10(act);
	if(strstr(a,"ln"))
	acting=log(act);
	//开方,指数,随机数
	if(strstr(a,"sqrt"))
	acting=sqrt(act);
	if(strstr(a,"exp"))
	acting=exp(act);
	if(strstr(a,"rand"))
	acting=rand0()*act;

	if (isalpha(a[0])||a[0]=='^'||a[0]=='!'||a[0]=='%')
	printf("=%g\n",acting);
	return acting;
}

/* 处理乘除并计算 */

double CX(void)
{
	double cs;
	double acting = HS(),act=0;
	while ((token[m] == '*') || (token[m] == '/'))
		switch (token[m])
		{
			case '*':
			token[++m] = str[t++];
			act = HS();
			printf("步骤%d: %g×%g",++x,acting,act);
			acting*=act;
			printf("=%g\n",acting);
			break;
			case '/':
			token[++m] = str[t++];
			cs = HS();
			if (cs == 0)/*除数为0时*/
			{
			printf("除数不能为零");
			}
			printf("步骤%d: %g÷%g",++x,acting,cs);
			acting/=cs;
			printf("=%g\n",acting);
			break;
		}
	return acting;
}

/* 处理加减并计算 */
double JJ(void)
{
	double acting = CX();
	double act=0;
	while ((token[m] == '+') || (token[m] == '-'))
		switch (token[m])
		{
			case '+':
			token[++m] = str[t++];
			act = CX();
			printf("步骤%d: %g+%g",++x,acting,act);
			acting+=act;
			printf("=%g\n",acting);
			break;
			case '-':
			token[++m] = str[t++];
			act = CX();
			printf("步骤%d: %g-%g",++x,acting,act);
			acting-=act;
			printf("=%g\n",acting);
			break;
		}
	return acting;
}

/* 处理括号,数字,小数点 */
double FS(void)
{
	double acting;
	char number[N];
	int i = 0;
	if (token[m] == '(')
	{
		token[++m] = str[t++];
		acting = JJ();
		if (token[m] == ')')
			token[++m] = str[t++];
	}
	else if (isdigit(token[m]) || token[m] == '.')
	{
		while (isdigit(token[m]) || token[m] == '.')	/* 将字符串转换为浮点数  */
		{
			number[i++] = token[m++];
			token[m] = str[t++];
		}
		number[i] = '\0';
		acting = atof(number);
	}
	return acting;
}

/*主函数*/
int main(void)
{
	double jg;
	int ms;
	printf("\033[47;34;5m\033[2J");
	//界面文本初始化
	printf(S1);
	while (true)//主循环
	{
		scanf("%s",str);
		ms=0;
		if (strstr(str,"tj"))
		{
			printf(S3);
			ms=1;
			while (ms)
			{
				scanf("%s",str);
				if (strstr(str,"exit"))
				{
					printf("\033[47;35m->已退出统计模式\n--------------------------------------------\n->查看函数说明请输入:hs\n->数据统计模式请输入:tj\n->输入表达式开始计算\n--------------------------------------------\n\033[47;30m");
				ms=0;
				strcpy(str,"0");
				}
				else
				if (strpbrk(str,d2)==NULL||strpbrk(str,d1)==NULL)
				printf("->输入错误\n");
				else
				math_hs(str);
			}
		}
		if (strstr(str,"hs"))
		{
		printf(S2);
		ms=1;
		}
		if (ms==0)
		{
		if ( str[0] == '-' || str[0] == '+' || str[0] == '*' || str[0] == '/' )
		{
			for ( int b = n;b >=1;b-- )
			str[b] = str[b-1];
			str[0] = '0';
		}
		c = 1;
		m = t = 0;
		token[m] = str[t++];
		printf("\033[47;34m");
		jg=JJ();
		printf("\033[47;31m计算结果: ");
		if (jg>MAX||jg<MIN||(jg>0&&jg<MIN_XS&&!strstr(str,"sin")&&!strstr(str,"cos")))
		printf("\033[47;31m=%g\n\033[47;30m",jg);
		else
		{
			if (PD==0)
			printf("\033[47;31m=%d\n\033[47;30m",(int)jg);
			else
			printf("\033[47;31m=%lf\n\033[47;30m",jg);
		}
		printf("--------------------------------------------\n");
		if (c == 1)//计算后,str清零
		{
			strcpy(str,"\0");
			x=c=jg = 0;
		}
		}
	}
	return 0;
}



版权声明:本文为qbdmm原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。