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

📄 calculation.cpp

📁 1、二进制、八进制、十进制及十六进制数的加、减、乘、除、乘方、取模等简单计算 2、科学计算函数
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Calculation.cpp: implementation of the CCalculation class.
// Made by Gamsn in 10.26.2005
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Calculator123.h"
#include "Calculation.h"
#include "math.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define FUNCNUM 16 //函数个数
#define CONSTNUM 11 //常数个数
#define E 2.7182818284590452353
#define PI 3.1415926535897932384

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCalculation::CCalculation()
{
	//初始化函数和常数
	m_bDegree=0;
	m_nOutputFlag=0;
	opt[0]="e^";
	opt[1]="ch";
	opt[2]="sqr";
	opt[3]="sh";
	opt[4]="log";
	opt[5]="cos";
	opt[6]="sin";
	opt[7]="tan";
	opt[8]="ln";
	opt[9]="abs";
	opt[10]="at";
	opt[11]="as";
	opt[12]="ac";
	opt[13]="th";
	opt[14]="exp";
    opt[15]="cot";
	opt2[0]='^';
	opt2[1]='-';
	opt2[2]='+';
	opt2[3]='%';
	opt2[4]='*';
	opt2[5]='/';
	m_strConValue[0]="3.1415926535897932384";	m_strConName[0]="PI";
	m_strConValue[1]="9.80665";					m_strConName[1]="GG";
	m_strConValue[2]="(8.988*10^9)";			m_strConName[2]="EF";
	m_strConValue[3]="0.02241383";				m_strConName[3]="VM";
	m_strConValue[4]="(1.380662*10^(-23))";		m_strConName[4]="BC";
	m_strConValue[5]="8.3144";					m_strConName[5]="MG";
	m_strConValue[6]="(6.6720*10^(-11))";		m_strConName[6]="GR";
	m_strConValue[7]="(6.022045*10^23)";		m_strConName[7]="NA";
	m_strConValue[8]="(2.99792458*10^8)";		m_strConName[8]="LS";
	m_strConValue[9]="(8.854187818*10^(-12))";	m_strConName[9]="DC";
	m_strConValue[10]="2.7182818284590452353";	m_strConName[10]="E";
}

CCalculation::~CCalculation()
{

}

bool CCalculation::IsDigital(CString str)
{
	while(str.GetAt(0)=='-') str.Delete(0);
	for(int i=0;i<FUNCNUM;i++) if(str.Find(opt[i])!=-1) return 0;
	for(i=0;i<6;i++) if(str.Find(opt2[i])!=-1) return 0;
	return 1;
}

CString CCalculation::NtoS(double d)
{
	int  decimal, sign;
	char *buffer;
	buffer = _ecvt( d, 16, &decimal, &sign );
	CString str=buffer;
	if(decimal>=0 && decimal<=16) str.Insert(decimal,".");
	else if(decimal>16)
	{
		for(int i=str.GetLength();i<decimal;i++) str+="0";
		str+=".0";
	}
	else 
	{
		for(int i=0;i<-decimal;i++)	str.Insert(0,"0");
		str.Insert(0,".");
	}
	if(sign==1) str.Insert(0,"-");
	return str;
}

double CCalculation::StoN(CString str)
{
	char   *stopstring;
	double x;
    x = strtod( str.GetBuffer(0), &stopstring );
	m_strTmp=stopstring;
	return x;
}

CString CCalculation::TwoE(CString store)
{
	double x2,y,x1=StoN(store);
	store=m_strTmp;
	char op=store.GetAt(0);
	store.Delete(0);
	x2=StoN(store);
	if(m_strTmp!="") return "ERROR_"+m_strTmp+"未知符号_";
	if(op=='+') {y=x1+x2;}
	else if(op=='*') {y=x1*x2;}
	else if(op=='-') {y=x1-x2;}
	else if(op=='^') {y=pow(x1,x2);}
	else if(op=='/') {y=x1/x2;}
	else if(op=='%') {y=fmod(x1,x2);}
	else return "ERROR_"+m_strTmp+"未知运算符_";
	return NtoS(y);
}

CString CCalculation::SingleE(CString op,double dx)
{
	if(op=="ln") 
	{
		return NtoS(log(dx));
	}
	else if(op=="log") 
	{
		return NtoS(log10(dx));
	}
	else if(op=="sqr") 
	{
		return NtoS(sqrt(dx));
	}
	else if(op=="e^") 
	{
		return NtoS(exp(dx));
	}
	else if(op=="abs") 
	{
		return NtoS(fabs(dx));
	}
	else if(op=="ac") 
	{  
		if(m_bDegree)
	 return NtoS(acos(dx)*180/PI);
		else
			return NtoS(acos(dx));
	}
	else if(op=="as") 
	{
        if(m_bDegree)
		return NtoS(asin(dx)*180/PI);
	    else
        return NtoS(asin(dx));
	}
	else if(op=="at") 
	{
	    if(m_bDegree)
        return NtoS(atan(dx)*180/PI);
		else
		return NtoS(atan(dx));
	}

	if(m_bDegree) dx=dx*PI/180;
	if(op=="tan") 
	{
		return NtoS(tan(dx));
	}
	else if(op=="sin") 
	{	
		return NtoS(sin(dx));			
	}
	else if(op=="cos") 
	{
		return NtoS(cos(dx));		
	}
	else if(op=="cot") 
	{
		return NtoS(1/tan(dx));		
	}
	else if(op=="sh") 
	{
		return NtoS(sinh(dx));				
	}	
	else if(op=="ch") 
	{
		return NtoS(cosh(dx));
	}
	else if(op=="th") 
	{
		return NtoS(sinh(dx)/cosh(dx));
	}
	else if(op=="exp") 
	{
		return NtoS(pow(10,dx));
	}
	return "ERROR"+op+"_未知函数_";
}

int CCalculation::LocateLBra(CString store)
{
	int len=store.GetLength();
	int pos=-1;
	for(int i=0;i<len;i++)
	{
		if(pos>=0 && store.GetAt(i)==')') break;
		if(store.GetAt(i)=='(')
		{
			pos=i;
		}
	}
	return pos;
}

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

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

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

CString CCalculation::MainPro(CString store)
{
	if(store.IsEmpty()) return "表达式不能为空";
	int p=store.Find("--");             
	      if(p!=-1)								//把负负替换为正
		  {
			store.Delete(p,2);
		    store.Insert(p,"+");
			if(store.GetAt(0)=='+') store.Delete(0);
		  } 
	int j;
	for(j=0;j<store.GetLength();j++)       //处理存在+或-号并没有数字参数的情况
	{
		if(store.GetAt(j)=='-'||store.GetAt(j)=='+')
		{    
			if(j+1==store.GetLength()||(store.GetAt(j+1)<'0'||(store.GetAt(j+1)>'9'&&store.GetAt(j+1)<'A')||(store.GetAt(j+1)>'Z'&&store.GetAt(j+1)<'a')||store.GetAt(j+1)>'z')&&store.GetAt(j+1)!='(')
				store.Insert (j+1,'0');

		}
	} 

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

⌨️ 快捷键说明

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