简单计算器一、基本功能描述二进制、八进制、十进制及十六进制数的加、减、乘、除、乘方、取模等简单计算科学计算函数,包括(反)正弦、(反)余弦、(反)正切、(反)余切、开方、指数等函数运行以角度、弧度两种方式实现上述部分函数具备历史计算的记忆功能对不正确的表达式能指出其错误原因二、流程图图1 输入数据子函数流程图图2三、 设计步骤打开Microsoft Visual C++ ,在文件中点击新建,在弹出框内选择MFC AppWizard[exe]工程,输入工程名Calculter 及其所在位置,点击确定,如图3所示。
N输入数据子函数图3 新建MFC AppWizard[exe]工程将弹出MFC AppWizard-step 1对话框,选择基本对话框,点击完成,如图4所示。
图4 基本对话框这样,MFC AppWizard就建立了一个基于对话窗口的程序框架,如图5所示。
图5 新建的对话框四、界面设计1、创建控件在图5所示的Resoure View选项卡中打开Dialog资源组,双击IDD_CALCULATOR_DIALOG,在右边的窗口中显示出待编辑的对话框。
开始摆放控件,包括编辑框和按钮的创建。
按钮的创建以“1”为例进行介绍,其他按钮的创建可参照此进行操作。
1)在图5中Controls的“编辑框”按钮上单击鼠标左键,在对话框编辑窗口上合适的位置按下鼠标左键并拖动鼠标画出一个大小合适的编辑框。
在编辑框上单击鼠标右键,在弹出的快捷莱单中选择属性选项,此时弹出Edit属性对话框,如图6所示,在该对话框中输入ID属性。
图6 Edit属性对话框2)在图3中Controls的“Button”按钮上单击鼠标左键,在对话框上的合适的位置上按下鼠标左键并拖动鼠标画出一个大小合适的下压式按钮。
在按钮上单击鼠标右键,在弹出的快捷菜单中选择属性选项,此时也弹出Push Button属性对话框,如图7所示,在该对话框中输入控件的ID值和标题属性。
图7 Push Button属性按照上面的操作过程编辑其他按钮和编辑框等对象的属性。
表1 各按钮和编辑框等对象的属性完成后界面如图8所示。
图8 计算器界面五、计算器源程序代码;else if(decimal>16){for(int i=();i<decimal;i++) str+="0";str+=".0";}else{for(int i=0;i<-decimal;i++) (0,"0");(0,".");}if(sign==1) (0,"-");return str;}double CCalculation::StoN(CString str){char *stopstring;double x;x = strtod( (0), &stopstring );m_strTmp=stopstring;return x;}CString CCalculation::TwoE(CString strExp){double x2,y,x1=StoN(strExp);strExp=m_strTmp;char op=(0);(0);x2=StoN(strExp);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"){return NtoS(acos(dx));}else if(op=="as"){return NtoS(asin(dx));}else if(op=="at"){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 strExp) {int len=();int pos=-1;for(int i=0;i<len;i++){if(pos>=0 && (i)==')') break;if(i)=='('){pos=i;}}return pos;}void CCalculation::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 CCalculation::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;}ind('-');if(tmpos==-1) break;else pos+=tmpos;if(pos==0 && 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('+');ind('+');if(pos==-1) break;etLength());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 CCalculation::ModiResult(CString strRes){if("#IN")!=-1) return "结果有溢出或值域越界";/*****************去掉保护括号**********************/ if(0)=='(') (0);if()-1)==')') ()-1);/***************************************************/ int pos=(".");CString str="";if(pos!=-1){if(pos==0) strRes="0"+strRes;else if(0)=='-' && (1)=='.') (1,"0");}if(pos>16){(pos);(1,".");("%d",pos-1);str=" E"+str;}pos=(".");if(pos==0 || pos==1 && (0)=='0'){for(int i=pos+1;i<();i++){if(i)!='0') break;}if(i>4){(" E-%d",i-2);(pos,i-1);(1,".");}}strRes=(pos+16)+str;;if(pos!=-1){strDF=()-pos-1);(pos,()-pos);}();len=();for(i=0;i<len;i++){ch=(i);dx+=(ch-48)*pow(8,i);}len=();for(i=0;i<len;i++){ch=(i);dx+=(ch-48)*pow(8,-i-1);}strTmp=NtoS(dx);strExp->Insert(index+1,strTmp);pos=strExp->Find("xo");}}void CCalculation::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);{ch=strExp->GetAt(i);if(ch>=48 && ch<=57 || ch>=97 && ch<=102 ||ch==46){(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<();i++){if(i)=='.') pos++;if(pos>1) {*strExp="ERROR_缺少二元运算符_";return;} }pos=(".");if(pos!=-1){strDF=()-pos-1);(pos,()-pos);}();len=();for(i=0;i<len;i++){ch=(i);if(ch>=48 && ch<=57);if(pos!=-1){strDF=()-pos-1);(pos,()-pos);}();len=();for(i=0;i<len;i++){ch=(i);dx+=(ch-48)*pow(2,i);}len=();{ch=(i);dx+=(ch-48)*pow(2,-i-1);}strTmp=NtoS(dx);strExp->Insert(index+1,strTmp);pos=strExp->Find("xb");}}void CCalculation::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(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";else ("%d",nTmp);nDecInt/=16;strExp->Insert(0,str);}*strExp+=".";if(pos!=-1){dDec=StoN(strDec);int nCount=0;while(dDec!=0){dDec*=16;int nTmp=dDec;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";else ("%d",nTmp);*strExp+=(pos);dDec-=nTmp;if(++nCount==17) break;}}if(bMinus) strExp->Insert(0,"-");if(strExp->Find("-1")!=-1 && bMinus!=1) *strExp="太大无法表示"; }void CCalculation::Dec2Oct(CString *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(0));strDec=strExp->Right(strExp->GetLength()-pos);}else{nDecInt=atoi(strExp->GetBuffer(0));}strExp->Empty();while(nDecInt!=0){int nTmp=nDecInt%8;("%d",nTmp);nDecInt/=8;strExp->Insert(0,str);}*strExp+=".";if(pos!=-1){dDec=StoN(strDec);int nCount=0;while(dDec!=0){dDec*=8;int nTmp=dDec;("%d",nTmp);*strExp+=(pos);dDec-=nTmp;if(++nCount==17) break;}}if(bMinus) strExp->Insert(0,"-");}void CCalculation::Dec2Bin(CString *strExp){bool bMinus=0;if(strExp->GetAt(0)=='-'){bMinus=1;strExp->Delete(0);}int pos=strExp->Find('.');CString str,strDec;_int64 nDecInt;double dDec;if(pos!=-1){strDec=strExp->Left(pos);{*strExp="太大无法转换";return;}nDecInt=atoi(0));strDec=strExp->Right(strExp->GetLength()-pos);}else{{*strExp="太大无法转换";return;}nDecInt=atoi(strExp->GetBuffer(0));}strExp->Empty();while(nDecInt!=0){_int64 nTmp=nDecInt%2;("%d",nTmp);nDecInt/=2;strExp->Insert(0,str);}*strExp+=".";if(pos!=-1){dDec=StoN(strDec);int nCount=0;while(dDec!=0){dDec*=2;int nTmp=dDec;("%d",nTmp);*strExp+=(pos);dDec-=nTmp;if(++nCount==17) break;}}if(bMinus) strExp->Insert(0,"-");}六、结论与心得体会七测试结果1.测试+ - * / PI运算2.测试sin cos tan cot3. 20的二进制八进制十六进制二进制八进制十六进制4.历史表达式5.错误判断。