calculatordlg.cpp

来自「vc计算器 有 二进制」· C++ 代码 · 共 1,623 行 · 第 1/3 页

CPP
1,623
字号
}

void CCalculatorDlg::DelBracket(CString *strExp)
{
	int pos=LocateLBra(*strExp);
	int i,len=strExp->GetLength();
	if(pos==-1)
	{
		*strExp="ERROR_无效表达式_";
		return;
	}
	for(i=pos;i<len;i++)
		if(strExp->GetAt(i)==')')
			break;
	CString str;
	str=strExp->Mid(pos+1,i-pos-1);
	MultiE(&str);
	strExp->Delete(pos,i-pos+1);
	strExp->Insert(pos,str);
}

void CCalculatorDlg::MultiE(CString *strExp)
{
	if(strExp->IsEmpty())
		*strExp="ERROR_函数表达式为空_";
	if(IsDigital(*strExp))
	{
		return;
	}
	while(1)/*处理所有的一元运算*/
	{
		for(int i=0;i<FUNCNUM;i++)
		{
			int pos=strExp->Find(opt[i]);
			if(pos!=-1)
			{
				CString str=strExp->Right(strExp->GetLength()-pos-opt[i].GetLength());
				double dx=StoN(str);
				if(m_strTmp==str) {*strExp="ERROR"+str+"_无法识别的函数_";return;}
				strExp->Delete(pos,strExp->GetLength()-pos);
				*strExp+=SingleE(opt[i],dx)+m_strTmp;
				MinusMinus(strExp);
				if(pos>=1)
				{
					char ch=strExp->GetAt(pos-1);
					if(ch>=48 && ch<=57)
					{*strExp="ERROR_缺少二元运算符_";return;}
				}
				break;
			}
		}
		if(i==FUNCNUM)
			break;
	}
	//按运算符优先级处理二元运算
	int pos=-1;
	while(1)
	{
		pos=strExp->Find('^');
		if(pos==-1)
			break;
		else
			Calcu(strExp,pos);
	}
	while(1)
	{
		pos=strExp->Find('/');
		if(pos==-1) break;
		else Calcu(strExp,pos);
	}
	while(1)
	{
		pos=strExp->Find('*');
		if(pos==-1) break;
		else Calcu(strExp,pos);
	}
	while(1)
	{
		pos=strExp->Find('%');
		if(pos==-1) break;
		else Calcu(strExp,pos);
	}
	pos=0;
	if(strExp->GetAt(0)=='-' || strExp->GetAt(0)=='+')
		strExp->Insert(0,"0");
	while(1)
	{
		int tmpos=strExp->Right(strExp->GetLength()-pos).Find('-');
		if(tmpos==-1)
			break;
		else
			pos+=tmpos;
		if(pos==0 && pos<strExp->GetLength() && strExp->GetAt(pos+1)=='-' || pos>0)
		{
			if(strExp->GetAt(pos+1)=='+')
			{
				strExp->Delete(pos+1);
				pos=0;
				continue;
			}
			/*********处理连减(如:----1)的情况***********/
			int nCount=0;
			while(1)
			{
				if(++pos>0)
				{
					if(strExp->GetAt(pos)!='-') break;
					else nCount++;
				}
				else break;
			}
			if(nCount>0) 
			{
				strExp->Delete(pos-nCount-1,nCount+1);
				if(nCount%2==0) strExp->Insert(pos-nCount-1,"-");
				else if(pos-nCount-1>0) strExp->Insert(pos-nCount-1,"+");
				pos=0;
				continue;
			}
			else pos--;
			/***********************************************/
			if(pos>0 && strExp->GetAt(pos-1)=='+') 
			{
				pos++;
				continue;
			}
			Calcu(strExp,pos);
		}
		else pos++;
	}
	pos=0;
	while(1)
	{
		pos=strExp->Find('+');
		if(pos==-1)
			break;
		if(pos==0 && strExp->GetAt(pos+1)=='+' || pos>0)
		{
			/*********处理连加(如:++++1)的情况***********/
			int nCount=0;
			while(1)
			{
				if(pos++>0 && pos<strExp->GetLength())
				{
					if(strExp->GetAt(pos)!='+')
						break;
					else nCount++;					
				}
				else break;
			}
			if(nCount>0) 
			{
				strExp->Delete(pos-nCount-1,nCount+1);
				strExp->Insert(pos-nCount-1,"+");
				pos=0;
				continue;
			}
			else pos--;
			/***********************************************/
			Calcu(strExp,pos);
		}
		else pos++;
	}
}

void CCalculatorDlg::Calcu(CString *strExp,int pos)
{
	char ch;
	for(int j=pos-1;j>=0;j--)
	{
		ch=strExp->GetAt(j);
		if(ch=='+' ||ch=='-' ||ch=='*'||ch=='/' ||ch=='%' ||ch=='^' )
		{
			if(j==0 && ch!='-') {*strExp="ERROR_缺少参数_";return;}
			if(j==0 && ch=='-') j=-1;//防止把负号误判为减号
			else if(j>0 && ch=='-' && !IsDigital(strExp->Mid(j-1,1))) j--;
			break;
		}
	}
	for(int k=pos+1;k<strExp->GetLength();k++)
	{
		ch=strExp->GetAt(k);
		if(ch=='+' ||ch=='-' ||ch=='*'||ch=='/' ||ch=='%' ||ch=='^' )
		{
			if(ch=='-' && k>pos+1) break;
			if(ch=='-' && k>0 &&  IsDigital(strExp->Mid(k+1,1)) ) k++;
			else break;
		}
	}
	CString strExp2=strExp->Mid(j+1,k-j-1);
	*strExp=strExp->Left(j+1)+TwoE(strExp2)+strExp->Right(strExp->GetLength()-k);
	if(strExp->Find("#IN")!=-1) {*strExp="ERROR_结果有溢出或值域越界_";return;}
	if(!SynRes(strExp)) {*strExp="ERROR_缺少运算符_";return;}
	MinusMinus(strExp);
}

CString CCalculatorDlg::MainPro(CString strExp)
{
	if(strExp.IsEmpty())
		return "表达式不能为空";
	Macro(&strExp);
	strExp.MakeLower(); //表达式全部小写
	/**********给表达式加上保护括号************/
	strExp.Insert(0,"(");
	strExp+=")";
	/******************************************/
	int pos=strExp.Find(" ");
	int n=BraCheck(strExp);
	CString str;
	str.Format("%d",abs(n));
	if(n==1)
		strExp+=")";
	else
		if(n==-1)
			strExp.Insert(0,"(");
		else
			if(n>0)
				return "缺少"+str+"个右括号";
			else
				if(n<0)
					return "缺少"+str+"个左括号";
	while(pos!=-1) //去掉表达式中的空格符
	{
		strExp.Delete(pos);
		pos=strExp.Find(" ");
	}
	Oct2Dec(&strExp); //将表达式中的八进制数转换成十进制
	Hex2Dec(&strExp); //将表达式中的十六进制数转换成十进制
	Bin2Dec(&strExp); //将表达式中的二进制数转换成十进制
	while(!IsDigital(strExp))
	{
		DelBracket(&strExp);
		if(!SynRes(&strExp))
			return strExp;
	}
	if(!SynRes(&strExp)) return strExp;
	else return ModiResult(strExp);
}

void CCalculatorDlg::Macro(CString *strExp)  //寻找表达式中有无常数
{
	int pos;
	for(int i=0;i<CONSTNUM;i++)
	{
		pos=strExp->Find(m_strConName[i]);
		while(pos!=-1)
		{
			strExp->Delete(pos,m_strConName[i].GetLength());
			strExp->Insert(pos,m_strConValue[i]);
			if(pos>=1)
			{
				char ch=strExp->GetAt(pos-1);
				if(ch>=48 && ch<=57 || ch==41)
				{
					*strExp="缺少二元运算符";
					return;
				}
			}
			pos=strExp->Find(m_strConName[i]);
		}
	}
}

CString CCalculatorDlg::ModiResult(CString strRes)
{
	if(strRes.Find("#IN")!=-1) return "结果有溢出或值域越界";
	/*****************去掉保护括号**********************/
	if(strRes.GetAt(0)=='(') strRes.Delete(0);
	if(strRes.GetAt(strRes.GetLength()-1)==')') strRes.Delete(strRes.GetLength()-1);
	/***************************************************/
	int pos=strRes.Find(".");CString str="";
	if(pos!=-1)
	{
		if(pos==0) strRes="0"+strRes;
		else if(strRes.GetAt(0)=='-' && strRes.GetAt(1)=='.') strRes.Insert(1,"0");
	}
	if(pos>16)
	{
		strRes.Delete(pos);
		strRes.Insert(1,".");
		str.Format("%d",pos-1);
		str=" E"+str;
	}
	pos=strRes.Find(".");
	if(pos==0 || pos==1 && strRes.GetAt(0)=='0')
	{
		for(int i=pos+1;i<strRes.GetLength();i++)
		{
			if(strRes.GetAt(i)!='0') break;
		}
		if(i>4)
		{
			str.Format(" E-%d",i-2);
			strRes.Delete(pos,i-1);
			strRes.Insert(1,".");
		}
	}
	strRes=strRes.Left(pos+16)+str;//截取小数点后16位
	return strRes;
}

bool CCalculatorDlg::SynRes(CString *strExp)
{
	int pos=strExp->Find("ERROR");
	if(pos!=-1)
	{
		pos=strExp->ReverseFind('_');
		strExp->Delete(pos,strExp->GetLength()-pos);
		pos=strExp->ReverseFind('_');
		strExp->Delete(0,pos+1);
		return 0;
	}
	return 1;
}

void CCalculatorDlg::MinusMinus(CString *strExp)
{
	int pos=strExp->Find("--");
	if(pos!=-1)
	{
		strExp->Delete(pos,2);
		strExp->Insert(pos,"+");
		if(strExp->GetAt(0)=='+') strExp->Delete(0);
	}
}

int CCalculatorDlg::BraCheck(CString str)
{
	int lb=0,rb=0,len=str.GetLength();
	for(int i=0;i<len;i++)
	{
		if(str.GetAt(i)=='(') lb++;
		else if(str.GetAt(i)==')') rb++;
	}
	return lb-rb;
}

void CCalculatorDlg::Oct2Dec(CString *strExp)
{
	int len,i,index,pos=strExp->Find("xo");
	CString strTmp,strDF;
	char ch;
	double dx;
	while(pos!=-1)
	{
		dx=0;strTmp="";strDF="";
		strExp->Delete(pos,2);
		for(i=pos-1;i>=0;i--)
		{
			ch=strExp->GetAt(i);
			if(ch==56 || ch==57 || ch>=97 && ch<=102) 
			{
				*strExp="ERROR_八进制数越界_";
				return;
			}
			if(ch>=48 && ch<=55 ||ch==46)
			{
				strTmp.Insert(0,strExp->Mid(i,1));
				strExp->Delete(i);
			}
			else break;
		}
		if(i==pos-1) {*strExp="ERROR_缺少二元运算符_";return;}
		index=i;
		pos=strTmp.Find(".");
		if(pos!=-1)
		{
			strDF=strTmp.Right(strTmp.GetLength()-pos-1);
			strTmp.Delete(pos,strTmp.GetLength()-pos);
		}
		strTmp.MakeReverse();
		len=strTmp.GetLength();
		for(i=0;i<len;i++)
		{
			ch=strTmp.GetAt(i);
			dx+=(ch-48)*pow(8,i);
		}
		len=strDF.GetLength();
		for(i=0;i<len;i++)
		{
			ch=strDF.GetAt(i);
			dx+=(ch-48)*pow(8,-i-1);
		}
		strTmp=NtoS(dx);
		strExp->Insert(index+1,strTmp);

		pos=strExp->Find("xo");
	}
}

void CCalculatorDlg::Hex2Dec(CString *strExp)
{
	int len,i,index,pos=strExp->Find("xh");
	CString strTmp,strDF;
	char ch;
	double dx;
	while(pos!=-1)
	{
		dx=0;strTmp="";strDF="";
		strExp->Delete(pos,2);
		for(i=pos-1;i>=0;i--)
		{
			ch=strExp->GetAt(i);
			if(ch>=48 && ch<=57 || ch>=97 && ch<=102 ||ch==46)
			{
				strTmp.Insert(0,strExp->Mid(i,1));
				strExp->Delete(i);
			}
			else break;
		}
		if(i==pos-1) {*strExp="ERROR_缺少二元运算符_";return;}
		index=i;
		pos=0;
		for(i=0;i<strTmp.GetLength();i++)
		{
			if(strTmp.GetAt(i)=='.') pos++;
			if(pos>1) {*strExp="ERROR_缺少二元运算符_";return;}
		}
		pos=strTmp.Find(".");
		if(pos!=-1)
		{
			strDF=strTmp.Right(strTmp.GetLength()-pos-1);
			strTmp.Delete(pos,strTmp.GetLength()-pos);
		}
		strTmp.MakeReverse();
		len=strTmp.GetLength();
		for(i=0;i<len;i++)
		{
			ch=strTmp.GetAt(i);
			if(ch>=48 && ch<=57)//该数在0~9之间
			{
				dx+=(ch-48)*pow(16,i);
			}
			else if(ch>=97 && ch<=102)//该数在a~f之间
			{
				dx+=(ch-87)*pow(16,i);
			}
		}
		len=strDF.GetLength();
		for(i=0;i<len;i++)
		{
			ch=strDF.GetAt(i);
			if(ch>=48 && ch<=57)//该数在0~9之间
			{
				dx+=(ch-48)*pow(16,-i-1);
			}
			else if(ch>=97 && ch<=102)//该数在a~f之间
			{
				dx+=(ch-87)*pow(16,-i-1);
			}
		}
		strTmp=NtoS(dx);
		strExp->Insert(index+1,strTmp);
		pos=strExp->Find("xh");
	}
}

void CCalculatorDlg::Bin2Dec(CString *strExp)
{
	int len,i,index,pos=strExp->Find("xb");
	CString strTmp,strDF;
	char ch;
	double dx;
	while(pos!=-1)
	{
		dx=0;strTmp="";strDF="";
		strExp->Delete(pos,2);
		for(i=pos-1;i>=0;i--)
		{
			ch=strExp->GetAt(i);
			if(ch>=50 && ch<=57 || ch>=97 && ch<=102) 
			{
				*strExp="ERROR_二进制数越界_";
				return;
			}
			if(ch=='0' || ch=='1' ||ch==46)
			{
				strTmp.Insert(0,strExp->Mid(i,1));
				strExp->Delete(i);
			}
			else break;
		}
		if(i==pos-1) {*strExp="ERROR_缺少二元运算符_";return;}
		index=i;
		pos=strTmp.Find(".");
		if(pos!=-1)
		{
			strDF=strTmp.Right(strTmp.GetLength()-pos-1);
			strTmp.Delete(pos,strTmp.GetLength()-pos);
		}
		strTmp.MakeReverse();
		len=strTmp.GetLength();
		for(i=0;i<len;i++)
		{
			ch=strTmp.GetAt(i);
			dx+=(ch-48)*pow(2,i);
		}
		len=strDF.GetLength();
		for(i=0;i<len;i++)
		{
			ch=strDF.GetAt(i);
			dx+=(ch-48)*pow(2,-i-1);
		}
		strTmp=NtoS(dx);
		strExp->Insert(index+1,strTmp);
		pos=strExp->Find("xb");
	}
}

void CCalculatorDlg::Dec2Hex(CString *strExp/*strExp须为数字*/)
{
	bool bMinus=0;
	if(strExp->GetAt(0)=='-') 
	{
		bMinus=1;
		strExp->Delete(0);
	}
	int pos=strExp->Find('.');
	CString str,strDec;
	int nDecInt;
	double dDec;
	if(pos!=-1) 
	{
		strDec=strExp->Left(pos);
		nDecInt=atoi(strDec.GetBuffer(0));
		strDec=strExp->Right(strExp->GetLength()-pos);	
	}
	else
	{
		nDecInt=atoi(strExp->GetBuffer(0));
	}
	strExp->Empty();
	while(nDecInt!=0)
	{
		int nTmp=nDecInt%16;
		if(nTmp==10) str="a";
		else if(nTmp==11) str="b";
		else if(nTmp==12) str="c";
		else if(nTmp==13) str="d";
		else if(nTmp==14) str="e";
		else if(nTmp==15) str="f";

⌨️ 快捷键说明

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