表达式解析计算器源码完整实现

大一下时做的大数非图形界面计算器,自己在这个过程中收获较大,希望和大家分享

微笑

分三个(面向过程浮点版,面向对象浮点版和面向对象大数版)版本::

完整实现如下:

Version1:

面向过程浮点版

(从文件读入并输出

divexcept.h(存储各种错误信息)

#include <iostream>
#include <string>
using namespace std;
string return_except(int sign)
{
	
	string errortype;
	if(sign==1)errortype="运算符错位/(Primary Expected)";
	else if(sign==2)errortype="多余运算符/(Unexpected Token)";
    else if(sign==3)errortype="出现非法字符/(Invalid Characters)";
    else if(sign==4)errortype="右括号多于左括号/(Too Many Right Parentheses)";
    else if(sign==5)errortype="变量名命名错误/(Unexpected Token)";
    else if(sign==6)errortype="除零错误/(Divide By Zero)";
    else if(sign==7)errortype="变量名过长/(Too Long Name Of Variables)";
    else if(sign==8)errortype="未定义变量/(Undefined Variables)";
    else if(sign==9)errortype="乘号缺失/(Multiple Sign Expected)"; 
    else if(sign==10)errortype="左右括号不匹配/(Parentheses Matching Failed)";
    return errortype;
}


pre_check.h(解析表达式前,对表达式进行预判)

#include <iostream>
#include <string>
#include <map>
using namespace std;
string validchars="0123456789*/+-=()_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMnopQRSTUVWXYZ ";
string tmp="";
int precheck(string s)
{
	int count=0;
	tmp="";
	int sign=0;//因错误类型繁多,故设定sign值为0时,判断无错误。 
	int leftp=0,rightp=0;//分别表示左右括号数。
	s=' '+s;//便于后续过程处理 
	int len=s.length();
	//报错类型1,运算符错位,(Primary Expected),括号内的独立表达式会在下述循环中处理 。
	if(s[1]=='*'||s[1]=='/'||s[1]=='=')
	{                                                      
		sign=1;
		return sign;
	}
	//报错类型2,多余运算符,(Unexpected Token),式子中的将在循环中处理。 
	if(s[len-1]=='+'||s[len-1]=='*'||s[len-1]=='/'||s[len-1]=='-'||s[len-1]=='=')
	{
		sign=2;
		return sign;
	} 
	for(int i=1;i<s.length();i++)
	{
	   //报错类型3,合法字符中找不到该字符,(Bad Token)。
		if(validchars.find(s[i])==-1)
		{
			sign=3;
		    return sign;
		} 
		if(s[i]=='(')leftp++;
		else if(s[i]==')')rightp++;
		//报错类型4,右括号多于左括号,(Too Many Right Parentheses)。
		if(rightp>leftp)
		{
			sign=4;
			return sign; 
		}
		//报错类型5,变量名命名错误,数字后不能再跟字母,(Unexpected Token)。
		if(isalpha(s[i])&&isdigit(s[i-1])) 
		{
			sign=5;
			return sign; 
		}
		//报错类型6,除零错误,此处只能初判直接除以0的错误,运算中将继续检查(Divide By Zero)。

		if(s[i-1]=='/'&&s[i]=='0')
		{
			sign=6;
			return sign; 
		} 
		//报错类型1,运算符错位,(Priamry Expected)。 
		if((s[i-1]=='+'||s[i-1]=='-'||s[i-1]=='*'||s[i-1]=='/'||s[i-1]=='=')
		&&(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'||s[i]=='='))
		{
			sign=1;
			return sign;
		}
		if((s[i-1]=='(')&&(s[i]=='='||s[i]=='*'||s[i]=='/'))
		{
			 sign=1;
			 return sign;
		} 
		//报错类型2,多余运算符,(Unexpected Token)。 
		if((s[i]==')')&&(s[i-1]=='='||s[i-1]=='+'||s[i-1]=='-'||s[i-1]=='*'||s[i-1]=='/'))
		{
			sign=2;
			return sign;
		}
		//报错类型9,不能省略乘号,(Multiple Sign Can't Be Ignored)。
		if((s[i]=='('&&isalnum(s[i-1]))||(s[i-1]==')'&&isalnum(s[i])))
		{
			sign=9;
			return sign;
		}
		//统计=号个数 
		if(s[i]=='=')count++; 
	}
	//左右括号不匹配,报错类型10(Parentheses Matching Failed)。
    if(leftp!=rightp) 
    {
	  sign=10;
	  return sign;
    }
    if(count)//代表是赋值表达式,处理全是数字的变量错误 
	{
		int count1=0;
		s[0]='=';   //将表达式变成 =123=234从而方便判断 
		for(int i=1;i<s.length();i++)
		{
			if(s[i]=='=')count1++;
			if(s[i]<='9'&&s[i]>='0'&&s[i-1]=='='&&count1!=count)
			{
				sign=5;
				return sign;
			}
		}
	} 
    return sign;
}


main.cpp

#include <fstream>
#include <iostream>
#include <map> 
#include <string>
#include <iomanip>
#include "divexcept.h"
#include "pre_check.h"
using namespace std;
double term(),factor(),expr(),number();
void assignment(); 
string var(),original,store;//original为预处理后的表达式 
int pos;//pos计算过程中的光标位置 
map <string,double> vars;//储存变量 
int presign=0;//预判过程中的错误标记,0认无错误	
int tmpsign=0;//文法解析过程中的错误标记,0认无错误 
ifstream in("in.txt");
ofstream out("out.txt");
void assignment()
{
    //如若已出错,直接返回 
    if(tmpsign) return;  
    string varName[20]; //最多支持20个变量的连等
    double val;
	int n=0;	     
    while(1) 
      {   
          int var_begin=pos;  
	      if(isalpha(original[pos])||original[pos]=='_') //表示读入变量名
		  { 
		      string temp=var();    
		      if(temp!="")  varName[n++]=temp;//""代表出现过长变量名,已处理
			  else break;	
              if(pos!=original.length()-1&&original[pos]=='=')   ++pos; 
              else 
	  	      {
		          pos=var_begin; //变量名后面不再是等号,把变量名回吐
		          n--; 
				  break;   
              }
           } 
	      else break;//已读不到变量名 
      }	  
	 val=expr();   
     if(!tmpsign)//代表没有出现任何异常 
     {
       for(int i=0;i<n;i++) vars[varName[i]]=val;//把变量及值放入map
       out<<"Assignment Succeed!/赋值成功\n";
       for(int i=0;i<n;i++)out<<varName[i]<<": "<<vars[varName[i]]<<" ";
       out<<endl;
	   return ;   
     }
     else return;
}

double expr(void)
{ 
     //如若已出错,直接返回 
      if(tmpsign) return 0;    
      double result_expr;
      //若出现其它运算符,已在预判中报错 
      if(original[pos]=='-'){ ++pos;result_expr=-term();}
	  else result_expr=term();
      while(1)
      {   
	      if(original[pos]=='+')
	      {  
		    ++pos;  
			result_expr+=term();
          }
	      else if(original[pos]=='-')
		  {  
		     ++pos; 
			 result_expr-=term();
		  }
		  else break;
      }
      return result_expr;
}

double term(void)
{ 
     //如若已出错,直接返回 
      if(tmpsign) return 0; 
      double result_term=factor();
      while(1)
      {
          if(original[pos]=='*') 
		  {  
		     ++pos;  
			 result_term*=factor();
          }
	      else if(original[pos]=='/')
		  { 
		     ++pos;
		    double temp=1.0*factor();//除法特殊处理 
			if(temp==0.0)
			{
				tmpsign=6;
				return 0;
			} 
			else result_term/=temp;
          }
		  else break;
      }
      return result_term;
}

double factor(void)
{ 
      //如若已出错,直接返回 
      if(tmpsign) return 0;  
      double result_factor;
      if(original[pos]=='(')
      {   
	      ++pos;  //跳过左括号 
	      //flag=1;
          if(original[pos]=='_'||isalpha(original[pos])) assignment(); //赋值表达式   
          else   result_factor=expr();//普通表达式
          ++pos; //跳过右括号,右括号异常已在预判中处理 
          //flag=0;
      }
      else if(isdigit(original[pos]))  result_factor=number();
	  else  if(original[pos]=='_'||isalpha(original[pos]))
  	  {
		  string vn=var();//取变量名
		  map<string,double>::iterator  it;
	      it=vars.find(vn); 
          if(it!=vars.end())result_factor= it->second;
          //报错类型8,未定义变量,通过tmpsign反映出错,计算仍将继续 
          else	{tmpsign=8;return 0;}				
      }
	  //报错类型2,Unexpected Token。 
	 else     {tmpsign=2;return 0;} 
     return result_factor;
}

double number(void)
{  
     //如若已出错,直接返回 
      if(tmpsign) return 0;    
	  double num=0;
      while(isdigit(original[pos]))
      {  
        num=10.0*num+(original[pos]-'0');
	    ++pos;
      }
      return num;
}

string var(void)
{
     //如若已出错,直接返回 
      if(tmpsign) return "";          
	  string  varName;       
	  int n=0;
	  if(original[pos]=='_'||isalpha(original[pos]))
		  varName+=original[pos++];
      while(original[pos]=='_'||isalnum(original[pos]))
         varName+=original[pos++]; 
      //变量名过长,报错类型7,将变量名置为空,代表赋值不成功
      if(varName.length()>20)
      {
      	 tmpsign=7;
		 varName=""; 
      }
      return varName;
}
int main() 
{

	while(getline(in,store))
	{
		int is_assignment=0;
		//original初始化 
		original="";
		for(int i=0;i<store.size();i++)// 支持空格读入 
		{
			if(store[i]!=' ')
			original+=store[i];
		}
		pos=0;
        tmpsign=0;//认无错 
		presign=precheck(original);// 先进行简单错误的预判 
		if(!presign)
		{
			double ans=0;
			if(original.find('=')!=-1)//判断是否为表达式,此处只区分赋值和非赋值表达式 
			{
			  assignment();
			  is_assignment=1;
			}
			else  ans=expr();
            if(!tmpsign&&!is_assignment)out<<"The result of  ("<<original<<")   is: "<<fixed<<setprecision(6)<<ans<<endl; 
	        else if(tmpsign)out<<return_except(tmpsign)<<endl;
		}
		else out<<return_except(presign)<<endl;
	}
	return 0;
}


Version2:

面向对象浮点版

divexcept.h与except.h与上同


programm.h(解析头文件)

#include <string>
#include <map>
#include <fstream>
using namespace std;
class Program
{
    int presign;//预判过程中的错误标记,0认无错误	
    int tmpsign;//文法解析过程中的错误标记,0认无错误  
    int pos;//pos计算过程中的光标位置 
   	string original,store;//original为预处理后的表达式 
    map <string,double> vars;//储存变量 
public:
	Program()
	{  
	  ifstream in("in.txt");
      ofstream out("out.txt");
	};
	void run();
	double term(),number();
    void assignment(); 
    string var();
};

programm.cpp(解析具体实现)

#include <fstream>
#include <iostream>
#include <map> 
#include <string>
#include <iomanip>
#include "divexcept.h"
#include "pre_check.h"
#include "program.h"
using namespace std;
ifstream in("in.txt");
ofstream out("out.txt");
void Program::  assignment()
{
    //如若已出错,直接返回 
    if(tmpsign) return;  
    string varName[20]; //最多支持20个变量的连等
    double val;
	int n=0;	     
    while(1) 
      {   
          int var_begin=pos;  
	      if(isalpha(original[pos])||original[pos]=='_') //表示读入变量名
		  { 
		      string temp=var();    
		      if(temp!="")  varName[n++]=temp;//""代表出现过长变量名,已处理
			  else break;	
              if(pos!=original.length()-1&&original[pos]=='=')   ++pos; 
              else 
	  	      {
		          pos=var_begin; //变量名后面不再是等号,把变量名回吐
		          n--; 
				  break;   
              }
           } 
	      else break;//已读不到变量名 
      }	  
	 val=expr();   
     if(!tmpsign)//代表没有出现任何异常 
     {
       for(int i=0;i<n;i++) vars[varName[i]]=val;//把变量及值放入map
       out<<"Assignment Succeed!/赋值成功\n";
       for(int i=0;i<n;i++)out<<varName[i]<<": "<<vars[varName[i]]<<" ";
       out<<endl;
	   return ;   
     }
     else return;
}

double Program::  expr(void)
{ 
     //如若已出错,直接返回 
      if(tmpsign) return 0;    
      double result_expr;
      //若出现其它运算符,已在预判中报错 
      if(original[pos]=='-'){ ++pos;result_expr=-term();}
	  else result_expr=term();
      while(1)
      {   
	      if(original[pos]=='+')
	      {  
		    ++pos;  
			result_expr+=term();
          }
	      else if(original[pos]=='-')
		  {  
		     ++pos; 
			 result_expr-=term();
		  }
		  else break;
      }
      return result_expr;
}

double Program::  term(void)
{ 
     //如若已出错,直接返回 
      if(tmpsign) return 0; 
      double result_term=factor();
      while(1)
      {
          if(original[pos]=='*') 
		  {  
		     ++pos;  
			 result_term*=factor();
          }
	      else if(original[pos]=='/')
		  { 
		     ++pos;
		    double temp=1.0*factor();//除法特殊处理 
			if(temp==0.0)
			{
				tmpsign=6;
				return 0;
			} 
			else result_term/=temp;
          }
		  else break;
      }
      return result_term;
}

double Program::  factor(void)
{ 
      //如若已出错,直接返回 
      if(tmpsign) return 0;  
      double result_factor;
      if(original[pos]=='(')
      {   
	      ++pos;  //跳过左括号 
	      //flag=1;
          if(original[pos]=='_'||isalpha(original[pos])) assignment(); //赋值表达式   
          else   result_factor=expr();//普通表达式
          ++pos; //跳过右括号,右括号异常已在预判中处理 
          //flag=0;
      }
      else if(isdigit(original[pos]))  result_factor=number();
	  else  if(original[pos]=='_'||isalpha(original[pos]))
  	  {
		  string vn=var();//取变量名
		  map<string,Unexpected Token。 
	 else     {tmpsign=2;return 0;} 
     return result_factor;
}

double Program::  number(void)
{  
     //如若已出错,直接返回 
      if(tmpsign) return 0;    
	  double num=0;
      while(isdigit(original[pos]))
      {  
        num=10.0*num+(original[pos]-'0');
	    ++pos;
      }
      return num;
}

string Program::  var(void)
{
     //如若已出错,直接返回 
      if(tmpsign) return "";          
	  string  varName;       
	  int n=0;
	  if(original[pos]=='_'||isalpha(original[pos]))
		  varName+=original[pos++];
      while(original[pos]=='_'||isalnum(original[pos]))
         varName+=original[pos++]; 
      //变量名过长,报错类型7,将变量名置为空,代表赋值不成功
      if(varName.length()>20)
      {
      	 tmpsign=7;
		 varName=""; 
      }
      return varName;
}
void Program:: run() 
{
	while(getline(in,store))
	{
	    presign=0;
		int is_assignment=0;
		//original初始化 
		original="";
		for(int i=0;i<store.size();i++)// 支持空格读入 
		{
			if(store[i]!=' ')
			original+=store[i];
		}
		pos=0;
        tmpsign=0;//认无错 
		presign=precheck(original);// 先进行简单错误的预判 
		if(!presign)
		{
			double ans=0;
			if(original.find('=')!=-1)//判断是否为表达式,此处只区分赋值和非赋值表达式 
			{
			  assignment();
			  is_assignment=1;
			}
			else  ans=expr();
            if(!tmpsign&&!is_assignment)out<<"The result of  ("<<original<<")   is: "<<fixed<<setprecision(6)<<ans<<endl; 
	        else if(tmpsign)out<<return_except(tmpsign)<<endl;
		}
		else out<<return_except(presign)<<endl;
	}
}

main.cpp

#include"program.h"
using namespace std;

int main()
{
	Program loader;
	loader.run();
}


Version3

面向对象大数版


divexcept.h与pre_check.h与上同


programm.h

#include <string>
#include <map>
#include <fstream>
#include "BigNum.h"
using namespace std;
class Program
{
    int presign;//预判过程中的错误标记,0认无错误	
    int tmpsign;//文法解析过程中的错误标记,0认无错误  
    int pos;//pos计算过程中的光标位置 
   	string original,string> vars;//储存变量 
public:
	Program()
	{  
	  ifstream in("in.txt");
      ofstream out("out.txt");
	};
	void run();
	BigNum term(),number();
    void assignment(); 
    string var();
};


programm.cpp

#ifndef PROGRAM
#define PROGRAM
#include <fstream>
#include <iostream>
#include <map> 
#include <string>
#include <iomanip>
#include "divexcept.h"
#include "pre_check.h"
#include "program.h"
using namespace std;
ifstream in("in.txt");
ofstream out("out.txt");
void Program::  assignment()
{
    //如若已出错,直接返回 
    if(tmpsign) return;  
    string varName[20]; //最多支持20个变量的连等
    BigNum val(0);
	int n=0;	     
    while(1) 
      {   
          int var_begin=pos;  
	      if(isalpha(original[pos])||original[pos]=='_') //表示读入变量名
		  { 
		      string temp=var();    
		      if(temp!="")  varName[n++]=temp;//""代表出现过长变量名,已处理
			  else break;	
              if(pos!=original.length()-1&&original[pos]=='=')   ++pos; 
              else 
	  	      {
		          pos=var_begin; //变量名后面不再是等号,把变量名回吐
		          n--; 
				  break;   
              }
           } 
	      else break;//已读不到变量名 
      }	  
	 val=expr();   
     if(!tmpsign)//代表没有出现任何异常 
     {
       for(int i=0;i<n;i++) vars[varName[i]]=val.get_total();//把变量及值放入map 
       out<<"Assignment Succeed!/赋值成功\n";
       for(int i=0;i<n;i++)out<<varName[i]<<": "<<vars[varName[i]]<<" ";
       out<<endl;
	   return ;   
     }
     else return;
}

BigNum Program::  expr(void)
{ 
     //如若已出错,直接返回 
      if(tmpsign) return (BigNum)0;    
      BigNum result_expr(0);
      //若出现其它运算符,已在预判中报错 
      if(original[pos]=='-'){ ++pos;result_expr-=term();}
	  else result_expr=term();
      while(1)
      {   
	      if(original[pos]=='+')
	      {  
		    ++pos;  
			result_expr+=term();
          }
	      else if(original[pos]=='-')
		  {  
		     ++pos; 
			 result_expr-=term();
		  }
		  else break;
      }
      return result_expr;
}

BigNum Program::  term(void)
{ 
     //如若已出错,直接返回 
      if(tmpsign) return (BigNum)0; 
      BigNum result_term=factor();
      while(1)
      {
          if(original[pos]=='*') 
		  {  
		     ++pos;  
			 result_term*=factor();
          }
	      else if(original[pos]=='/')
		  { 
		     ++pos;
		    BigNum temp=factor();//除法特殊处理 
			if(temp==0)
			{
				tmpsign=6;
				return (BigNum)0;
			} 
			else result_term=result_term/temp;
          }
          else if(original[pos]=='%')
          {
          	 ++pos;
          	 BigNum temp=factor();
          	 if(temp==0)
          	 {
 	           tmpsign=11;
				return (BigNum)0;	
             }
          }
		  else break;
      }
      return result_term;
}

BigNum Program::  factor(void)
{ 
      string temp1;
      //如若已出错,直接返回 
      if(tmpsign) return (BigNum)0;  
      BigNum result_factor(0);
      if(original[pos]=='(')
      {   
	      ++pos;  //跳过左括号 
	      //flag=1;
          if(original[pos]=='_'||isalpha(original[pos])) assignment(); //赋值表达式   
          else   result_factor=expr();//普通表达式
          ++pos; //跳过右括号,右括号异常已在预判中处理 
          //flag=0;
      }
      else if(isdigit(original[pos]))  result_factor=number();
	  else  if(original[pos]=='_'||isalpha(original[pos]))
  	  {
		  string vn=var();//取变量名
		  map<string,string>::iterator  it;
	      it=vars.find(vn); 
          if(it!=vars.end())
		  	{
		      temp1=it->second;
		      result_factor=(BigNum)temp1;
		  	}
          //报错类型8,未定义变量,通过tmpsign反映出错,计算仍将继续 
          else	{tmpsign=8;return(BigNum) 0;}				
      }
	  //报错类型2,Unexpected Token。 
	 else     {tmpsign=2;return (BigNum)0;} 
     return result_factor;
}

BigNum Program::  number(void)
{  
     //如若已出错,直接返回 
      if(tmpsign) return (BigNum)0;    
	  BigNum num(0);
      while(isdigit(original[pos]))
      {  
        num=(BigNum)10*num+(original[pos]-'0');
	    ++pos;
      }
      return num;
}

string Program::  var(void)
{
     //如若已出错,直接返回 
      if(tmpsign) return "";          
	  string  varName;       
	  int n=0;
	  if(original[pos]=='_'||isalpha(original[pos]))
		  varName+=original[pos++];
      while(original[pos]=='_'||isalnum(original[pos]))
         varName+=original[pos++]; 
      //变量名过长,报错类型7,将变量名置为空,代表赋值不成功
      if(varName.length()>20)
      {
      	 tmpsign=7;
		 varName=""; 
      }
      return varName;
}
void Program:: run() 
{
	while(getline(in,store))
	{
	    presign=0;
		int is_assignment=0;
		//original初始化 
		original="";
		for(int i=0;i<store.size();i++)// 支持空格读入 
		{
			if(store[i]!=' ')
			original+=store[i];
		}
		pos=0;
        tmpsign=0;//认无错 
		presign=precheck(original);// 先进行简单错误的预判 
		if(!presign)
		{
			BigNum ans(0);
			if(original.find('=')!=-1)//判断是否为表达式,此处只区分赋值和非赋值表达式 
			{
			  assignment();
			  is_assignment=1;
			}
			else  ans=expr();
            if(!tmpsign&&!is_assignment)out<<"The result of  ("<<original<<")   is: "<<fixed<<setprecision(6)<<ans<<endl; 
	        else if(tmpsign)out<<return_except(tmpsign)<<endl;
		}
		else out<<return_except(presign)<<endl;
	}
}
#endif

大数类定义实现:

Bignum.h

#ifndef BIGNUM_HEADER
#define BIGNUM_HEADER
#include<iostream>
using namespace std;

class BigNum{
  int _sign;//0表示没有负号,1表示有负号 
  string _num;
public:
  BigNum(const string& a = "0" );
  BigNum(const int &x=0);
  friend BigNum operator+( const BigNum& a,const BigNum& b );
  friend BigNum operator-( const BigNum& a,const BigNum& b );
  friend BigNum operator*( const BigNum& a,const BigNum& b );
  friend BigNum operator/( const BigNum& a,const BigNum& b );
  friend BigNum operator%( const BigNum& a,const BigNum& b );
  string get_total()
  {
  	return (_sign==1?"-":"")+_num;
  }
  BigNum& operator+=(const BigNum& a){ return *this = *this + a; }
  BigNum& operator-=(const BigNum& a){ return *this = *this - a; }
  BigNum& operator*=(const BigNum& a){ return *this = *this * a; }
  BigNum& operator/=(const BigNum& a){ return *this = *this / a; }
   BigNum& operator%=(const BigNum& a){ return *this = *this / a; }
  friend bool operator==(const BigNum& a,const BigNum& b);
  friend istream& operator>>(istream& in,BigNum& a);
  friend ostream& operator<<(ostream& out,const BigNum& a);
};//-----------------------------------
#endif   


BigNum.cpp

#ifndef BIGNUM2
#define BIGNUM2
#include "BigNum.h"
#include <string>
#include <string.h>
string add(string a,string b);
string sub(string a,string b);
string div(string a,string b);
string mult(string a,string b);
string cal(string a,string b);
string mod(string a,string b);
//-------------------------------------
BigNum::BigNum(const string& a)//构造函数 
{
   if(a[0]=='-') 
   {
     _sign=1;
     _num=a.substr(1);
   }
   else 
   {
     _sign=0;
     _num=a;
   }   
}//------------------------------------
BigNum::BigNum(const int& x)//构造函数 
{
	string tmp="";
	if(x==0)tmp="0";
	int temp;
	if(x<0)_sign=1;
	else _sign=0;
    temp=abs(x);
    while(temp)
    {
    	tmp+=(temp%10+'0');
    	temp/=10;
    }
    reverse(tmp.begin(),tmp.end());
    _num=tmp;
}//------------------------------------
bool comp(string a,string b)
{
	if(a.length()<b.length())return true;
	else if(a.length()>b.length())return false;
	else
	{
			bool flag=0;
			for(int i=0;i<a.length();i++)
			{
				if(a[i]<b[i])return true;
				else if(a[i]>b[i])return false;
			}
			return flag;//a==b
	}
}
BigNum operator+( const BigNum& a,const BigNum& b )
{
  
  string tmp1=a._num,tmp2=b._num,ans;
  if(a._sign==1)tmp1='-'+tmp1;
  if(b._sign==1)tmp2='-'+tmp2;
  ans=cal(tmp1,tmp2);
  BigNum ret(ans);
  return ret;
}//------------------------------------
BigNum operator-( const BigNum& a,const BigNum& b )
{
  string tmp1=a._num,ans;
  tmp2='-'+tmp2;
  if(a._sign==1)tmp1='-'+tmp1;
  ans=cal(tmp1,tmp2);
  BigNum ret(ans);
  return ret;
}//------------------------------------
BigNum operator*( const BigNum& a,ans;  
  ans=mult(tmp1,tmp2);
  if(!((a._sign==1&&b._sign==1)||(a._sign==0&&b._sign==0)))
  ans='-'+ans;
  BigNum ret(ans);
  return ret;
}//------------------------------------

BigNum operator/( const BigNum& a,ans;  
  ans=div(tmp1,tmp2);
  if((a._sign&&!b._sign)||(!a._sign&&b._sign))
  ans='-'+ans;
  BigNum ret(ans);
  return ret; 
}//------------------------------------*/
BigNum operator%( const BigNum& a,ans;  
  ans=mod(tmp1,tmp2);
  BigNum ret(ans);
  return ret; 
}//------------------------------------*/

istream& operator>>(istream& in,BigNum& a)
{
  string s;  in>>s;
  a = BigNum(s);
  return in;
}//------------------------------------
ostream& operator<<(ostream& out,const BigNum& a)
{
  return out<<(a._sign?"-":"") << a._num;
}//------------------------------------

bool operator==(const BigNum& a,const BigNum& b)
{
  return a._sign==b._sign && a._num==b._num;
}//------------------------------------




//----------------------------------------
string add(string s1,string s2)
{
	reverse(s1.begin(),s1.end());//反转 
	reverse(s2.begin(),s2.end());
	s1+=string(205-s1.length(),'0');//补0 
	s2+=string(205-s2.length(),'0');
	int flag=0,p;
	for(int i=0;i<205;i++)
	{
		s1[i]=flag+s1[i]+s2[i]-'0';//加法计算过程 
		if(s1[i]>'9'){  s1[i]-=10; flag=1;}
		else flag=0;
	}
	reverse(s1.begin(),s1.end());//再反回来 
	p=s1.find_first_not_of('0');//去除多余的0 
	if(p!=-1)
	s1=s1.substr(p);
	else s1="0";
	return s1;
}
//----------------------------------------------------------
string sub(string s1,string s2)
{
   int sign,l1,l2,symbol;//sign表运算正负性,symbol表s1,s2长度 
   string tmp1,tmp2;
   if(s1[0]=='-')
   {
   	  tmp1=s1.substr(1);
   	  tmp2=s2;
   	  if(tmp1.length()>tmp2.length())sign=0;
   	  else if(tmp2.length()>tmp1.length())sign=1;
   	  else
   	  {
   	  	sign=1;//如果两数刚好相等,那么认不需'-'号 
  	   	for(int i=0;i<tmp1.length();i++)
  	   	{
	   	  	if(tmp1[i]>tmp2[i]){sign=0;symbol=0;break;}
	   	  	else if(tmp1[i]<tmp2[i]){sign=1;symbol=1;break;}
        }
      }
   }
   else
   {
   	  tmp1=s1;
   	  tmp2=s2.substr(1);
   	  if(tmp1.length()>tmp2.length())sign=1;
   	  else if(tmp2.length()>tmp1.length())sign=0;
   	  else
   	  {
   	  	sign=1;//如果两数刚好相等,那么认不需'-'号 
  	   	for(int i=0;i<tmp1.length();i++)
  	   	{
	   	  	if(tmp1[i]>tmp2[i]){sign=1;symbol=0;break;}
	   	  	else if(tmp1[i]<tmp2[i]){sign=0;symbol=1;break;}
        }
      }
   }
    reverse(tmp1.begin(),tmp1.end());
    reverse(tmp2.begin(),tmp2.end());
    l1=tmp1.length();
    l2=tmp2.length();
   	tmp1+=string(205-tmp1.length(),'0');
	tmp2+=string(205-tmp2.length(),'0');
    int flag=0;
    if(l1>l2)
    {
    	for(int i=0;i<l1;i++)
    	{
	      tmp1[i]=tmp1[i]-tmp2[i]+'0'+flag;//减法计算过程 
		  if(tmp1[i]<'0')
		  	{
  			  tmp1[i]=tmp1[i]+10;
  			  flag=-1;
  		    }
		  else flag=0;	
	    }
    }
    else if(l2>l1)
    {
       	for(int i=0;i<l2;i++)
    	{
	      tmp1[i]=tmp2[i]-tmp1[i]+'0'+flag;
		  if(tmp1[i]<'0')
		  	{
  			  tmp1[i]=tmp1[i]+10;
  			  flag=-1;
  		    }
		  else flag=0;	
	    }
    }
	else
	{
	   if(symbol)
	   {
   		for(int i=0;i<l1;i++)
    	{
	      tmp1[i]=tmp2[i]-tmp1[i]+'0'+flag;
		  if(tmp1[i]<'0')
		  	{
  			  tmp1[i]=tmp1[i]+10;
  			  flag=-1;
  		    }
		  else flag=0;	
	    }
   	   }
	   else
	   {
	    for(int i=0;i<l1;i++)
    	{
	      tmp1[i]=tmp1[i]-tmp2[i]+'0'+flag;
		  if(tmp1[i]<'0')
		  	{
  			  tmp1[i]=tmp1[i]+10;
  			  flag=-1;
  		    }
		  else flag=0;	
	    }
   	   }	
	}
	reverse(tmp1.begin(),tmp1.end());
	int p=tmp1.find_first_not_of('0');
	if(p!=-1)
	tmp1=tmp1.substr(p);
	else tmp1="0";
	if(sign)return tmp1;   	
	else return '-'+tmp1;
}
//------------------------------------------------
string cal(string s1,string s2)
{
   if(s1[0]=='-'&&s2[0]=='-')
   {
   	  string tmp1,tmp2;
   	  tmp1=s1.substr(1);
   	  tmp2=s2.substr(1);
   	  s1='-'+add(tmp1,tmp2);
   }
   else if(s1[0]!='-'&&s2[0]!='-')
   {
   	  s1=add(s1,s2);
   }
   else
   {
   	  s1=sub(s1,s2);
   }
   return s1;	
} 
//--------------------------------------------
string mult(string x,string y)
{
	int ans[420],a[205],b[205];
	int flag=0;
	memset(ans,sizeof(ans));
	memset(a,sizeof(a));
	memset(b,sizeof(b));
	reverse(x.begin(),x.end());//反转  最低位对齐 
	reverse(y.begin(),y.end());
	for(int i=0;i<x.length();i++)a[i]=x[i]-'0';//转成数字 
	for(int i=0;i<y.length();i++)b[i]=y[i]-'0';
	for(int i=0;i<205;i++)
	{
		for(int j=0;j<205;j++)
		{
			ans[i+j]=ans[i+j]+a[i]*b[j];//列式累加,进位之后处理 
		}
	}
   for(int i=0;i<420;i++)
   {
   	 ans[i]=ans[i]+flag;//进位处理 
   	 flag=ans[i]/10;
   	 ans[i]%=10;
   }
   int p=0;                 
   for(int i=419;i>=0;i--)     
   {                           
	 if(ans[i]!=0)              
	 {                          
       p=i;                       
       break;	                       
     }                         
   } 
   string tmp=""; 
   for(int i=p;i>=0;i--)
   tmp+=(ans[i]+'0');
   return tmp;                       
}
string div(string a,string b)
{
	if(a.length()<b.length())return "0";
	else if(a==b) return "1";
	else if(a.length()==b.length())
	{
		if(comp(a,b))return "0";
		else 
		{
			int count=0;
			string tmp5,tmp6;
			tmp6='-'+b; 
           while(1)
            {
            	if(comp(a,b))break;
				a=cal(a,tmp6);
				count++;
            }
		   if(count==0)tmp5="0";
		   while(count)
		  {
		     tmp5+=(count%10+'0');
	         count/=10;	
		  }
		   reverse(tmp5.begin(),tmp5.end());
		   return tmp5;
		}
	}
	else
	{
		int l=a.length()-b.length(),count=0;
		string tmp,tmp1,tmp2,tmp3="",tmp7;//假设最大除以999...
		if(l!=0)tmp=a.substr(0,l);
		else tmp="0";
		tmp1=mult(tmp,b);
		tmp1='-'+tmp1;
		tmp2=sub(a,tmp1);
		tmp7='-'+b;
		while(1)
		{
			if(comp(tmp2,b))break;//判定tmp2是否小于b 
			else
			{
				tmp2=sub(tmp2,tmp7);
				count++;          //用count计数,等会再转为string 
			}
		} 
		if(count==0)tmp3="0";
		while(count)
		{
		   tmp3+=(count%10+'0');
		   count/=10;	
		}
		reverse(tmp3.begin(),tmp3.end());
		tmp=add(tmp,tmp3);
		return tmp;
	}
}
string mod(string a,string b)
{
	if(a.length()<b.length())return a;
	else if(a==b) return "0";
	else if(a.length()==b.length())
	{
		if(comp(a,b))return a;
		else 
		{
			string tmp5,tmp6);
            }
		   return a;
		}
	}
	else
	{
		int l=a.length()-b.length(),tmp7);
				count++;          //用count计数,等会再转为string 
			}
		} 
        return tmp2;
	}
}
#endif

main.cpp

#include <iostream>
#include "BigNum.h"
#include "program.h"
using namespace std;
int main()
{
	Program loader;
	loader.run();
}

相关文章

自1998年我国取消了福利分房的政策后,房地产市场迅速开展蓬...
文章目录获取数据查看数据结构获取数据下载数据可以直接通过...
网上商城系统MySql数据库设计
26个来源的气象数据获取代码
在进入21世纪以来,中国电信业告别了20世纪最后阶段的高速发...