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

📄 calc.c

📁 PDA程序开发PDA程序开发PDA程序开发PDA程序开发PDA程序开发PDA程序开发PDA程序开发PDA程序开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************/
/*==========================================================================
 *
 *  版权所有 (C) 2000-2001 吴柏建. All Rights Reserved.
 *
 *  文件:		Calc.c
 *  内容:		PSDE_DEMO_PDA之计算操作函数源文件。
 *  作者:		吴柏建
 *  制作日期:	2001.10.9
 *  修改日期:	2001..
 *
 ***************************************************************************/

/*CALC_IN_STRING_WAY宏有定义时表示使用字符串方式进行数值计算。*/
//#define CALC_IN_STRING_WAY

#ifndef CALC_IN_STRING_WAY
#include "stdio.h"
#include "math.h"
#endif

#include "pda.h"

#define UNDO	2
#define CE		3
#define CC		4

#define MC		5
#define MR		6
#define MS		7
#define MA		8

#define	DIV			9 /*/*/
#define	MUT			10/***/
#define	SUB			11/*-*/
#define	ADD			12/*+*/

#define	ROOT		13
#define	PERCENT		14
#define	RECIPROCAL	15/*倒数*/
#define	P_N			16/*+/-*/

#define MAXNUM		12/*计算器能接受的数字位数*/

typedef struct _CALCDATA
{
	unsigned char InOne[32];/*第一个操作数*/
	unsigned char Opt;/*操作符*/
	unsigned char InTwo[32];/*第二个操作数*/

	unsigned char OldIn[32];/*对操作符连操作的原始操作数*/
	unsigned char OldOpt;/*连操作的原始操作符*/

	unsigned char M[32];/*保存的数字字符串*/
	/*status:
	0:第一操作数插入改写,此时无操作符和第二个操作数。
	1:有第一个操作数和操作符但无第二个操作数。(此时'='表示对操作符连操作)
	2:第二个操作数插入改写,此时有第一个操作数、操作符。
	3:第二个操作数将被清零重输,由1,2状态通过单目操作符进入,重输后进入2,4,5状态。
	4:有第一个操作数表示结果将被清零重输,此时无操作符和第二个操作数。
	5:状态同4,但是由等于操作进入,显示函数中按显示精度舍入结果进入状态4。
	8:ERROR。
	*/
	unsigned char status;
}CALCDATA;

CALCDATA calc;





#ifdef CALC_IN_STRING_WAY
/*以下是不支持double型数据计算的代码*/
/*
不使用double型数据计算实现以下函数。内容:略。
void StrDIV(unsigned char *d,unsigned char *a,unsigned char *b);
void StrMUT(unsigned char *d,unsigned char *a,unsigned char *b);
void StrSUB(unsigned char *d,unsigned char *a,unsigned char *b);
void StrADD(unsigned char *d,unsigned char *a,unsigned char *b);
void StrROOT(unsigned char *d,unsigned char *a);
*/
/*不支持double型数据计算的代码结束*/
#else
/*以下是支持double型数据计算的代码*/
short StrCopy(unsigned char *d,unsigned char *s)
{
	short i=0;
	while(*s){i++;*d++=*s++;}
	*d=*s;
	return i;
}
/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
□---数字转换为字符串-------------------------------------------------□
□                                                                    □
□---2001.3.1---------------------------------------------------------□
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
void DoubleToStr(unsigned char *d,double i)
{
	unsigned char buf[32],*s,*e;
	sprintf(buf,"%12.13f",i);
	s=buf;
	while(*s==' ')s++;
	e=s;
	while(*e)e++;
	while(*--e=='0')*e=0;
	if(*s=='-')StrCopy(d,s);
	else
	{
		*d++='+';
		StrCopy(d,s);
	}
}
/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
□---字符串转换为数字-------------------------------------------------□
□                                                                    □
□---2001.3.1---------------------------------------------------------□
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
double StrToDouble(unsigned char *s)
{
	unsigned char c;
	unsigned char sign = 0;
	double	value = 0.0;
	double	fract = 0.1;
	c=*s++;
	if( c=='-'||c=='+')
	{
		if(c=='-')sign=1;
		c = *s++;
	}
	while((c>='0')&&(c<='9'))
	{
		value = value * 10.0 + (c - '0');
		c = *s++;
	}
	if(c=='.')
	{
		c=*s++;
		while((c>='0')&&(c<='9'))
		{
			value = fract * (c - '0') + value;
			fract /= 10.0;
			c=*s++;
		}
	}
	if( sign )value = -value;
	return value;
}
/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
□---计算器除法计算---------------------------------------------------□
□                                                                    □
□---2001.3.2---------------------------------------------------------□
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
void StrDIV(unsigned char *d,unsigned char *a,unsigned char *b)
{
	double dd,aa,bb;
	
	aa=StrToDouble(a);
	bb=StrToDouble(b);
	if(bb==0.0)d[1]='e';
	else
	{
		dd=aa/bb;
		DoubleToStr(d,dd);
	}
}
/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
□---计算器乘法计算---------------------------------------------------□
□                                                                    □
□---2001.3.2---------------------------------------------------------□
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
void StrMUT(unsigned char *d,unsigned char *a,unsigned char *b)
{
	double dd,aa,bb;

	aa=StrToDouble(a);
	bb=StrToDouble(b);
	dd=aa*bb;
	DoubleToStr(d,dd);
}
/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
□---计算器减法计算---------------------------------------------------□
□                                                                    □
□---2001.3.2---------------------------------------------------------□
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
void StrSUB(unsigned char *d,unsigned char *a,unsigned char *b)
{
	double dd,aa,bb;

	aa=StrToDouble(a);
	bb=StrToDouble(b);
	dd=aa-bb;
	DoubleToStr(d,dd);
}
/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
□---计算器加法计算---------------------------------------------------□
□                                                                    □
□---2001.3.2---------------------------------------------------------□
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
void StrADD(unsigned char *d,unsigned char *a,unsigned char *b)
{
	double dd,aa,bb;

	aa=StrToDouble(a);
	bb=StrToDouble(b);
	dd=aa+bb;
	DoubleToStr(d,dd);
}
/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
□---计算器根号计算---------------------------------------------------□
□                                                                    □
□---2001.3.2---------------------------------------------------------□
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
void StrROOT(unsigned char *d,unsigned char *a)
{
	double dd,aa;

	aa=StrToDouble(a);
	dd=sqrt(aa);/*平方根*/
	DoubleToStr(d,dd);
}


#endif/*支持double型数据计算的代码结束*/






/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
□---计算器数据结构初始化---------------------------------------------□
□                                                                    □
□---2001.3.1---------------------------------------------------------□
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
void InitCalc(void)
{
	calc.status=0;
	*calc.InOne='+';
	calc.InOne[1]=0;
	calc.Opt=0;
	*calc.InTwo='+';
	calc.InTwo[1]=0;
	calc.OldOpt=0;
}
/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
□---字符串处理进位---------------------------------------------------□
□   s指向字符串需要进位的地方。                                      □
□   返回TRUE表示进位导致字符串起点向前进一位,FALSE起点不变。        □
□---2001.3.3---------------------------------------------------------□
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
char EnterNum(unsigned char *s)
{
	unsigned char *d=s;
	*d--=0;
	while(1)
	{
		if(*d=='.'){d--;continue;}
		if(*d=='+'||*d=='-')
		{
			d--;*d=d[1];d[1]='1';*--s=0;return 1;
		}
		if(*d>='0'&&*d<='9')
		{
			*d+=1;
			if(*d<='9')return 0;
			else *d-=10;
			d--;
		}
		else return 0;
	}
}
/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
□---计算器输出显示---------------------------------------------------□
□                                                                    □
□---2001.3.3---------------------------------------------------------□
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
const unsigned char CalcStrError[]="error";
void CalcShow(void)
{
	short i,max;
	unsigned char *s,*ss,*d,buf[34];

	/*获取要显示的字符串指针*/
	s = (calc.Opt) ? calc.InTwo : calc.InOne;
	if(calc.status==4||calc.status==5||calc.status==1) s = calc.InOne;
	ss=s;
	/*检查整数部分是否超过MAXNUM并记录整数位数到i中*/
	for(d=s+1,i=0; *d; d++)
	{
		if(*d == '.')break;
		i++;
	}
	if(i>MAXNUM) calc.status = 8;
	max=i;
	/*检查字符串中是否有非法字符,通常由运算溢出或出错引入非法字符*/
	for(d=s+1; *d; d++)
	{
		if(*d!='.' && (*d<'0'||*d>'9') )
		{
			calc.status = 8;
			break;
		}
	}
AAA:
	/*处理好用来显示的字符串,放入指针d所指向的字符串中*/
	if(calc.status==8)d = (unsigned char *)CalcStrError;
	else
	{
		d=&buf[2];
		/*如字符串s为"-0"使之变为"+0"*/
		if(!s[1]||(s[1]=='0'&&s[2]==0))*s='+';
		/*Copy字符串s到字符串d,并消除d中的字符'+'*/
		if(*s=='+')StrCopy(&buf[1],s);
		else StrCopy(d,s);
		/*使s指针指向小数点,没有小数点时指向结束符*/
		for(s=d; *s&&*s!='.'; s++);
		if(*s)/*有小数点时*/
		{
			/*如显示数字超出长度,切断小数点后的多出部分*/
			while(*++s)
			{
				if(++i>=MAXNUM)
				{
					if(i>MAXNUM)s--;
					/*4舍5入*/
					if(*++s>='5')
					{
						if(EnterNum(s))
						{
							d--;
							s--;
							if(max+1>MAXNUM){ calc.status = 8;goto AAA;}
						}
					}
					else *s=0;
					break;
				}
			}
			/*显示的为计算结果时消除小数的尾'0'*/
			if(calc.status>=3||calc.status==1)
			{
				while(*--s=='0')*s=0;
			}
		}
		else/*无小数点时补上小数点*/
		{
			*s++='.';
			*s=0;
		}
		/*仅有小数点时小数点前加字符'0'*/
		if(*d=='.')
		{
			d[0]='0';
			d[1]='.';
			d[2]=0;
		}
	}
	/*计算结果舍入后重新作为操作数*/
	if(calc.status==5)
	{
		calc.status=4;
		if(*d=='-')StrCopy(calc.InOne,d);
		else StrCopy(calc.InOne,&buf[1]);
	}
	else if(calc.status!=0&&calc.status!=2)
	{
		if(*d=='0'&&d[1]=='.'&&d[2]==0)
		{
			*ss++='+';*ss=0;
		}
	}
	if(*d=='-'&&d[1]=='0'&&d[2]=='.'&&d[3]==0)d++;
	/*在适当的位置显示字符串*/
	i=GetStrLength(d)*8;
	DispBar(9,10,143,19,COLOR_WHITE);
	i=148-i;
	DispStr(i,13,d,COLOR15,COLOR0);
	/*显示或清除M*/
	i=(StrToDouble(calc.M)==0.0)?' ':'M';
	DispChar(13,10,i,COLOR15,COLOR0);

⌨️ 快捷键说明

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