如何用c語言做簡易計算器?.函數計算器是電子計算器的一種,可進行乘方、開方、指數、對數、三角函數、統計等方面的運算,又稱科學型計算器僅供參考:,下面我們就來聊聊關于如何用c語言做簡易計算器?接下來我們就一起去了解一下吧!
.
函數計算器是電子計算器的一種,可進行乘方、開方、指數、對數、三角函數、統計等方面的運算,又稱科學型計算器。僅供參考:
/*---------------------------------------
函數型計算器(VC 6.0,Win32 Console)
功能:
目前提供了10多個常用數學函數:
⑴正弦sin
⑵餘弦cos
⑶正切tan
⑷開平方sqrt
⑸反正弦arcsin
⑹反餘弦arccos
⑺反正切arctan
⑻常用對數lg
⑼自然對數ln
⑽e指數exp
⑾乘幂函數^
⑿向上取整ceil
⒀向下取整floor
⒁四舍五入取整round
用法:
如果要求2的32次幂,可以打入2^32<回車>
如果要求30度角的正切可鍵入tan(Pi/6)<回車>
注意不能打入:tan(30)<Enter>
如果要求1.23弧度的正弦,有幾種方法都有效:
sin(1.23)<Enter>
sin 1.23 <Enter>
sin1.23 <Enter>
如果驗證正餘弦的平方和公式,可打入sin(1.23)^2 cos(1.23)^2 <Enter>或sin1.23^2 cos1.23^2 <Enter>
此外兩函數表達式連在一起,自動理解為相乘如:sin1.23cos0.77 cos1.23sin0.77就等價于sin(1.23)*cos(0.77) cos(1.23)*sin(0.77)
當然你還可以依據三角變換,再用sin(1.23 0.77)也即sin2驗證一下。
本計算器充分考慮了運算符的優先級因此諸如:2 3*4^2 實際上相當于:2 (3*(4*4))
另外函數名前面如果是數字,那麼自動認為二者相乘.
同理,如果某數的右側是左括号,則自動認為該數與括弧項之間隐含一乘号。
如:3sin1.2^2 5cos2.1^2 相當于3*sin2(1.2) 5*cos2(2.1)
又如:4(3-2(sqrt5-1) ln2) lg5 相當于4*(3-2*(√5 -1) loge(2)) log10(5)
此外,本計算器提供了圓周率 Pi鍵入字母時不區分大小寫,以方便使用。
----------------------------------------*/
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <stdio.h>
#include <string.h>
#include <windows.h>
usingnamespacestd;
constcharTab=0x9;
constintDIGIT=1;
constintMAXLEN=16384;
chars[MAXLEN],*endss;
intpcs=15;
doubleround(doubledVal, shortiPlaces) {//iPlaces>=0
chars[30];
doubledRetval;
sprintf(s,"%.*lf",iPlaces,dVal);
sscanf(s,"%lf",&dRetval);
return(dRetval);
}
doublefun(doublex,charop[],int*iop) {
while(op[*iop-1]<32) //本行使得函數嵌套調用時不必加括号,如 arc sin(sin(1.234)) 隻需鍵入arc sin sin 1.234<Enter>
switch(op[*iop-1]) {
case7: x=sin(x); (*iop)--;break;
case8: x=cos(x); (*iop)--;break;
case9: x=tan(x); (*iop)--;break;
case10: x=sqrt(x); (*iop)--;break;
case11: x=asin(x); (*iop)--;break;
case12: x=acos(x); (*iop)--;break;
case13: x=atan(x); (*iop)--;break;
case14: x=log10(x); (*iop)--;break;
case15: x=log(x); (*iop)--;break;
case16: x=exp(x); (*iop)--;break;
case17: x=ceil(x); (*iop)--;break;
case18: x=floor(x); (*iop)--;break;
case19: x=round(x,0);(*iop)--;break;
}
returnx;
}
doublecalc(char*expr,char**addr) {
staticintdeep; //遞歸深度
staticchar*fname[]={"sin","cos","tan","sqrt","arcsin","arccos","arctan","lg","ln","exp","ceil","floor","round",NULL};
doubleST[10]={0.0}; //數字棧
charop[10]={' '}; //運算符棧
charc,*rexp,*pp,*pf;
intist=1,iop=1,last,i;
if(!deep) {
pp=pf=expr;
do{
c = *pp ;
if(c!=' '&& c!=Tab)
*pf = c;
} while(c!='\0');
}
pp=expr;
if((c=*pp)=='-'||c==' ') {
op[0] = c;
pp ;
}
last = !DIGIT;
while((c=*pp)!='\0') {
if(c=='(') {//左圓括弧
deep ;
ST[ist ]=calc( pp,addr);
deep--;
ST[ist-1]=fun(ST[ist-1],op,&iop);
pp = *addr;
last = DIGIT;
if(*pp == '('||isalpha(*pp) && strnicmp(pp,"Pi",2)) {//目的是:當右圓括弧的右恻為左圓括弧或函數名字時,默認其為乘法
op[iop ]='*';
last = !DIGIT;
c = op[--iop];
gotooperate ;
}
}
elseif(c==')') {//右圓括弧
pp ;
break;
} elseif(isalpha(c)) {
if(!strnicmp(pp,"Pi",2)) {
if(last==DIGIT) {
cout<< "π左側遇)"<<endl;exit(1);
}
ST[ist ]=3.14159265358979323846264338328;
ST[ist-1]=fun(ST[ist-1],op,&iop);
pp = 2;
last = DIGIT;
if(!strnicmp(pp,"Pi",2)) {
cout<< "兩個π相連"<<endl;exit(2);
}
if(*pp=='(') {
cout<< "π右側遇("<<endl;exit(3);
}
} else{
for(i=0; (pf=fname[i])!=NULL; i )
if(!strnicmp(pp,pf,strlen(pf))) break;
if(pf!=NULL) {
op[iop ] = 07 i;
pp = strlen(pf);
} else{
cout<< "陌生函數名"<<endl;exit(4);
}
}
} elseif(c==' '||c=='-'||c=='*'||c=='/'||c=='%'||c=='^') {
charcc;
if(last != DIGIT) {
cout<< "運算符粘連"<<endl;exit(5);
}
pp ;
if(c==' '||c=='-') {
do{
cc = op[--iop];
--ist;
switch(cc) {
case' ': ST[ist-1] = ST[ist];break;
case'-': ST[ist-1] -= ST[ist];break;
case'*': ST[ist-1] *= ST[ist];break;
case'/': ST[ist-1] /= ST[ist];break;
case'%': ST[ist-1] = fmod(ST[ist-1],ST[ist]);break;
case'^': ST[ist-1] = pow(ST[ist-1],ST[ist]);break;
}
} while(iop);
op[iop ] = c;
} elseif(c=='*'||c=='/'||c=='%') {
operate: cc = op[iop-1];
if(cc==' '||cc=='-') {
op[iop ] = c;
} else{
--ist;
op[iop-1] = c;
switch(cc) {
case'*': ST[ist-1] *= ST[ist];break;
case'/': ST[ist-1] /= ST[ist];break;
case'%': ST[ist-1] = fmod(ST[ist-1],ST[ist]);break;
case'^': ST[ist-1] = pow(ST[ist-1],ST[ist]);break;
}
}
} else{
cc = op[iop-1];
if(cc=='^') {
cout<< "乘幂符連用"<<endl;exit(6);
}
op[iop ] = c;
}
last = !DIGIT;
} else{
if(last == DIGIT) {
cout<< "兩數字粘連"<<endl;exit(7);
}
ST[ist ]=strtod(pp,&rexp);
ST[ist-1]=fun(ST[ist-1],op,&iop);
if(pp == rexp) {
cout<< "非法字符"<<endl;exit(8);
}
pp = rexp;
last = DIGIT;
if(*pp == '('||isalpha(*pp)) {
op[iop ]='*';
last = !DIGIT;
c = op[--iop];
gotooperate ;
}
}
}
*addr=pp;
if(iop>=ist) {
cout<< "表達式有誤"<<endl;exit(9);
}
while(iop) {
--ist;
switch(op[--iop]) {
case' ': ST[ist-1] = ST[ist];break;
case'-': ST[ist-1] -= ST[ist];break;
case'*': ST[ist-1] *= ST[ist];break;
case'/': ST[ist-1] /= ST[ist];break;
case'%': ST[ist-1] = fmod(ST[ist-1],ST[ist]);break;
case'^': ST[ist-1] = pow(ST[ist-1],ST[ist]);break;
}
}
returnST[0];
}
intmain(intargc,char**argv) {
inta;
if(argc<2) {
if(GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代碼頁
cout << "計算函數表達式的值。"<<endl<<"支持(), ,-,*,/,%,^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp,ceil,floor,round"<<endl;
while(1) {
cout << "請輸入表達式:";
gets(s);
if(s[0]==0) break;//
cout << s <<"=";
cout << setprecision(15) << calc(s,&endss) << endl;
}
} elseif(argc==2 && 0==strcmp(argv[1],"/?")) {
if(GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代碼頁
cout << "計算由≥1個命令行參數給出的函數表達式的值。最後一個參數是.0~.15表示将計算結果保留小數0~15位"<<endl<<"支持(), ,-,*,/,%,^^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp,ceil,floor,round"<<endl;
} else{
strncpy(s,argv[1],MAXLEN-1);s[MAXLEN-1]=0;
if(argc>2) {
for(a=2;a<argc-1;a ) strncat(s,argv[a],MAXLEN-1);//将空格間隔的各參數連接到s
if(1==sscanf(argv[a],".%d",&pcs) && 0<=pcs && pcs<=15) {//最後一個參數是.0~.15表示将計算結果保留小數0~15位
printf("%.*lf\n",pcs,calc(s,&endss));
} else{
strncat(s,argv[a],MAXLEN-1);
printf("%.15lg\n",calc(s,&endss));
}
} else{
printf("%.15lg\n",calc(s,&endss));
}
}
return0;
}
希望能對大家有所幫助,也期待大家指出問題;
如果有對這方面有興趣的可以加群:233026065,大家一起學習交流。
群内還有很多學習資料、書籍、視頻,免費課等等......
.
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!