/*---------------------------------------
函数型计算器(VC++6.0,Win32 Console)
程序由 yu_hua 于2007-07-27设计完成
功能:目前提供了10多个常用数学函数:
⑴正弦sin ⑵余弦cos ⑶正切tan
⑷开平方sqrt ⑸反正弦arcsin
⑹反余弦arccos ⑺反正切arctan
⑻常用对数lg ⑼自然对数ln
⑽e指数exp ⑾乘幂函数∧
用法:如果要求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>
using namespace std;
const char Tab=0x9;
const int DIGIT=1;
double fun(double x,char op[],int *iop)
{
while(op[*iop-1]<32) //本行使得函数嵌套调用时不必加括号
// 如 arc sin(sin(1.234)) 只需键入arc sin sin 1.234<Enter>
switch(op[*iop-1])
{
case 7: x=sin(x); (*iop)--;break;
case 8: x=cos(x); (*iop)--;break;
case 9: x=tan(x); (*iop)--;break;
case 10: x=sqrt(x); (*iop)--;break;
case 11: x=asin(x); (*iop)--;break;
case 12: x=acos(x); (*iop)--;break;
case 13: x=atan(x); (*iop)--;break;
case 14: x=log10(x);(*iop)--;break;
case 15: x=log(x); (*iop)--;break;
case 16: x=exp(x); (*iop)--;break;
}
return x;
}
double calc(char *expr,char **addr)
{
static deep; //递归深度
static char *fname[]={ "sin","cos","tan","sqrt",
"arcsin","arccos","arctan","lg","ln","exp",NULL};
double ST[10]={0.0}; //数字栈
char op[10]={'+'}; //运算符栈
char c,*rexp,*pp,*pf;
int ist=1,iop=1,last;
if(!deep)
{
pp=pf=expr;
do
{
c = *pp++;
if(c!=' '&& c!=Tab)
*pf++ = c;
}
while(c!=' ');
}
pp=expr;
if((c=*pp)=='-'||c=='+')
{
op[0] = c;
pp++;
}
last = !DIGIT;
while((c=*pp)!=' ')
{
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]; /////////////////////////////
goto operate ; /////////////////////////////
}
}
else if(c==')')//右圆括弧
{
pp++;
break;
}
else if(isalpha(c))
来源: