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

📄 calculate.c

📁 税控收款机源码:拼音输入法,LCD,VFD驱动,IC卡驱动,税控国标
💻 C
📖 第 1 页 / 共 2 页
字号:
#include  "include.h"

#define MAX_DIGIT 8
#define MAX_VALUE 99999999L
#define ADD_KEY		TOTAL
#define DIV_KEY     PRICE

#ifdef C6_VER
	#define SUB_KEY		CHECK
	#define MUL_KEY     CREDIT
	#define DIV_KEY     PRICE
	#define CAL_KEY00	0xff
#else
	#define SUB_KEY		DISCOUNT
	#define MUL_KEY     ADDITION
	#define DIV_KEY     PRICE
	#define CAL_KEY00	KEY00
#endif
	
/*=======================================================================;
 计算器程序函数
 主函数:void calculate();
 功能:实现四则运算.
 说明:按取消键退出,按清除键清除输入操作数,输入操作数和运算结果都不能超
       过999999,否则报错。
 设计编码:
 日期:2003.3.28
========================================================================*/
void calculate()   //main for calculate
{
  uchar xdata ch=0,status=0,len,op_flag,op_right,clear2line=0;
  uchar xdata str1[25],str2[12];
  uchar xdata prompt_str[25];
  uchar xdata CancelStr[]="按[取消]键返回";
  uchar xdata ErrStr0[]="表达式错误",ErrStr1[]="除数为零";
  uchar xdata ErrStr2[]="运算结果太大",ErrStr3[]="表达式为空";
  uchar* xdata OpErrStr[4]={ErrStr0,ErrStr1,ErrStr2,ErrStr3};

  Init_LCD_calculate();   //初始化lcd
  str1[0]='\0';
  str2[0]='\0';
  do
  {
    if(low_pwr) break;// 如果断电了,则exit;
    ch=CalWaitKey();
    if(ch==0x1b)ch='+';//合计键
    if(ch==VOID)      //按取消键立即返回
      break;
    else if(ch==CLEAR)  //清除键清掉输入的字符串str2,且状态转为0
    {
      if(clear2line)
      {
      	clear_lcd(1,1);
        clear2line=0;
        lcd_disp_flush_right(1,CancelStr);
      }
      str2[0]='\0';
      lcd_disp_flush_right(3,str2);
      status=0;
    }
    else if(ch==ENTER||ch==SUBTOTAL)  //确认键输出结果,状态转为0
    {
      if(clear2line)
      {
      	clear_lcd(1,1);
        clear2line=0;
        lcd_disp_flush_right(1,CancelStr);
      }
      strcat(str1,str2);
      len=strlen(str1);
      if(str1[len-1]=='+'||str1[len-1]=='-'||str1[len-1]=='*'||str1[len-1]=='/')
      	str1[len-1]='\0';
      op_right=OperateByStr(str1);  //入口str1运算表达式,出口str1为运算后的结果.
      if(op_right==0&&ch==ENTER)
      {
        prompt_str[0]='\0';
 	      strcat(prompt_str,"结果:");
        strcat(prompt_str,str1);
 	      lcd_disp_flush_right(2,prompt_str);
 //ning 03-04-20  	    len=strlen(prompt_str);
 ///ning 03-04-20    	  con_disp(2,24-len,4);    //"结果"要反显
      }
      else if(op_right==0&&ch==SUBTOTAL)
      {
        prompt_str[0]='\0';
        strcat(prompt_str,str1);
 	      lcd_disp_flush_right(2,prompt_str);
      }
      else 
      {
      	clear_lcd(1,1);
        lcd_disp(1,0,(uchar*)OpErrStr[op_right-1]);
	    con_disp(1,0,strlen((uchar*)OpErrStr[op_right-1]),
				(uchar*)OpErrStr[op_right-1]);
	    clear_lcd(2,2);
        clear2line=1;
      }
      if(ch==SUBTOTAL&&op_right==0)
	    	status=5;
	    else
      {
	     str1[0]='\0';     //使str1,str2为空
	     status=0;
	    }
      str2[0]='\0';
      lcd_disp_flush_right(3,str2);
    }
    else
    {
      if(!strlen(str1)&&!strlen(str2)&&ch=='-')
      {
      	str2[0]=ch;
      	str2[1]='\0';
      	op_flag=2;
      }
      else
        op_flag=AddCh(&status,str2,ch);
      if(op_flag==1)             //如op_flag为1,ch为运算符
      {
        strcat(str1,str2);
        op_right=OperateByStr1(str1);
        if(op_right)
 	   	  {
	   	   	clear_lcd(1,1);
  	      lcd_disp(1,0,(uchar*)OpErrStr[op_right-1]);
	      con_disp(1,0,strlen((uchar*)OpErrStr[op_right-1]),
				(uchar*)OpErrStr[op_right-1]);
  	      clear_lcd(2,2);
  	      str1[0]='\0';
  	      str2[0]='\0';
  	      clear2line=1;
  	      continue;
  	    }
   	    str2[0]='\0';
        lcd_disp_flush_right(2,str1);
      }
      if(op_flag)  //表示是可接受了字符,就刷新LCD
      {
        if(clear2line)
        {
          clear_lcd(1,1);
          clear2line=0;
          lcd_disp_flush_right(1,CancelStr);
        }    	
        lcd_disp_flush_right(3,str2);
      }
    }    
  }while(ch!=VOID);
  return;    
}
//===========================================================================
void Init_LCD_calculate(void)
{
  uchar xdata CalcStr[]="计算器",CancelStr[]="按[取消]键返回";

  clear_lcd(0,4);
  lcd_disp(0,0,CalcStr);
  lcd_disp_flush_right(1,CancelStr);
}

/*===================================
功能:正常显示为向右对齐显示,如str的长度超过24,则不显示,并返回1。
str为要显示的字符串。
====================================*/
uchar lcd_disp_flush_right(uchar line,uchar *str)
{
  uchar xdata i,col,ret,dstr[25];
  

	memset(dstr,0,25);
  for (i=0;i<25;i++)
   if(str[i]=='\0')
     break;
  if(i>=25)
  {
    ret=1;
    str[24]='\0';
    i=24;
  }
  if((24-i)%2)
    dstr[0]=' ';
  strcat(dstr,str);
  col=(24-i)/2;
  clear_lcd(line,1);
  lcd_disp(line,col,dstr);
  return 0;
}

/*=========================================
功能:实现入口参数str表示的表达式的运算,应保证表达式正确,如表达式有错,
则不运算,出口str为运算后的值。入口出口都是用ASCII码表示。返回值0表示正确,
其它为错误类型:1.表达式错,2.除数为零。3.操作数或中间结果或结果大于
999999.99,4.表达式为空
========================================================*/
uchar OperateByStr(uchar *str)
{
  uchar  xdata i=0,press_point=0;	
  uchar xdata ch,len,opp1,opp2;
  uchar xdata opd_pos=1,point_flag=0,negative_flag=0,err;  //opd_pos表示操作数位置
  long  xdata result,opd1=0,opd2=0,opd3=0,whole=0,part=0;

  len=strlen(str);
  if (len==0)
    return 4;        //表达式为空
  for(i=0;i<len;i++)
  {
    ch=str[i];
    if(i==0&&(ch=='+'||ch=='-'))   //第一个数前有符号
    {
      if(ch=='-')
        negative_flag=1;
       else
        negative_flag=0;
    }
    else if(ch>='0'&&ch<='9')
    {
    	if(!press_point)
    		whole=whole*10+(ch-'0')*100;
    	else
    	{
    		if(press_point==1)
    			part=(ch-'0')*10;
    		else
    			part=part+(ch-'0');
    		press_point++;
    	}
    	ch=str[i+1];
    	if((ch<'0'||ch>'9')&&(ch!='.'))
    	{
	      if(opd_pos==1)
  	      opd1=whole+part;
    	  else if(opd_pos==2)
      	  opd2=whole+part;
	      else if(opd_pos==3)
  	      opd3=whole+part;
  	  }
    }
    else if(ch=='+'||ch=='-'||ch=='*'||ch=='/')
    {
    	press_point=0;
    	whole=0;
      part=0;
      if(opd_pos==1)
        opp1=ch;
      else if(opd_pos==2)
        opp2=ch;
      ch=str[i+1];
      if((ch>='0'&&ch<='9')||(ch=='.'))
        opd_pos++;  //操作数位置加1
      else
        return 1;   //运算符必跟操作数
    }
    else if(ch=='.')
      press_point=1;
    else
      return 1;    //含有非法字符
  }   //end for
  
  if(negative_flag)
    opd1=-opd1;
  if((opp1=='/'&&opd2==0)||(opp2=='/'&&opd3==0))  //检查除数为零
     return 3;
  if(opd_pos==1)
    result=opd1;
  else if(opd_pos==2)
  {
    err=OperateByLong(opp1,opd1,opd2,&result);
    if(err)
      return err;
  }
  else if(opd_pos==3)
  {
    err=OperateByLong(opp2,opd2,opd3,&result);
    if(err)
      return err;
    err=OperateByLong(opp1,opd1,result,&result);
	  if(err)
  		return err;
  }
  LongToString(result,str);
  len=strlen(str);
  if(result==0)
  {
  	str[0]='0';
  	str[1]='\0';
  }
  else if(result>-10&&result<10&&result!=0)  //一位数
  {
    for(i=len+1;i>0;i--)	
    {
    	ch=str[i-1];
    	if(ch=='-')
    		break;
    	else
      	str[i+2]=str[i-1];
    }
    str[i]='0';
    str[i+1]='.';
    str[i+2]='0';
  }
  else if((result>-100&&result<=-10)||(result>=10&&result<100))//两们数
  {
    for(i=len+1;i>0;i--)	
    {
    	ch=str[i-1];
    	if(ch=='-')
    		break;
    	else
      	str[i+1]=str[i-1];
    }
    str[i]='0';
    str[i+1]='.';
  }
  else  //三位数以上
  {
    for(i=len;i>len-3;i--)	
      str[i+1]=str[i];
    str[i+1]='.';
    if(str[i+2]=='0'&&str[i+3]=='0')
      str[i+1]='\0';
  }
  return 0;
}

/*=================================================================
功能:对长整形数加减乘除,
返回0表示计算正确,
返回2表示除数为0
返回3表示数溢出,即结果大于MAX_VALUE或小于-MAX_VALUE
=================================================================*/
uchar OperateByLong(uchar opp,long opd1,long opd2,long *result)  //两个长整形实现四则运算
{
  uchar xdata err=0;	
//  long  xdata mod;
  
  switch(opp)
  {
    case '+':  *result=opd1+opd2;
               if (*result>MAX_VALUE||*result<-MAX_VALUE)
                 err=3;
               break;
    case '-':  *result=opd1-opd2;
               if (*result>MAX_VALUE||*result<-MAX_VALUE)

⌨️ 快捷键说明

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