永发信息网

C++ 数值精度。如我输入sin30°(应该为0.5),可是却等于0.49999999.请看下我的程序,是哪里的问题?

答案:3  悬赏:60  手机版
解决时间 2021-04-09 00:16
#include
#include
#include
#include
#include
#include
using namespace std;
const char Tab=0x9;
const int DIGIT=1;
double fun(double x,char op[],int *iop)
{
while(op[*iop-1]<32)
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!='\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];
goto operate ;
}
}
else if(c==')')
{
pp++;
break;
}
else if(isalpha(c))
{
if(!strnicmp(pp,"Pi",2))
{
if(last==DIGIT){cout<< "π左侧遇)" <ST[ist++]=3.14159265358979323846;
ST[ist-1]=fun(ST[ist-1],op,&iop);
pp += 2;
last = DIGIT;
if(!strnicmp(pp,"Pi",2)){cout<< "两个π相连" <if(*pp=='('){cout<< "π右侧遇(" <}
else
{
for(int 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<< "陌生函数名" <}
}
else if(c=='+'||c=='-'||c=='*'||c=='/'||c=='^')
{
char cc;
if(last != DIGIT){cout<< "运算符粘连" <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] = pow(ST[ist-1],ST[ist]);break;
}
}
while(iop);
op[iop++] = c;
}
else if(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] = pow(ST[ist-1],ST[ist]);break;
}
}
}
else
{
cc = op[iop-1];
if(cc=='^'){cout<< "乘幂符连用" <op[iop++] = c;
}
last = !DIGIT;
}
else
{
if(last == DIGIT){cout<< "两数字粘连" <ST[ist++]=strtod(pp,&rexp);
ST[ist-1]=fun(ST[ist-1],op,&iop);
if(pp == rexp){cout<< "非法字符" <
pp = rexp;
last = DIGIT;
if(*pp == '('||isalpha(*pp))
{
op[iop++]='*';
last = !DIGIT;
c = op[--iop];
goto operate ;
}
}
}
*addr=pp;
if(iop>=ist){cout<< "表达式有误" <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] = pow(ST[ist-1],ST[ist]);break;
}
}
return ST[0];
}
int main()
{
char s[128],*end;
while(1)
{
cout << "请输入表达式:";
cin.getline(s,128);
cout << setprecision(17) << calc(s,&end) << endl;
}
return 0;
}
最佳答案
在浮点计算中,存在误差是不可避免的
0.5表示成0.49999999,误差在允许范围内的
全部回答
没办法,这个函数是用浮点型运算的,结果有误差。
sin115°=sin(180°-65°)=sin65°=cos(90°-65°)=cos25° =cos(30°-5°)=cos30°cos5°+sin30°sin5° =sin5°/2+√3cos5°/2, 下面计算sin5°和cos5°.. 需要用到sin15°=(√6-√2)/4, 由于sin(3x)=3sinx-4sinx^3, 有sin15°=3sin5°-4sin5°^3, 即4sin5°^3-3sin5°+(√6-√2)/4=0, 解一元三次方程4x^3-3x+(√6-√2)/4=0在(0,1)的根.. 这个很复杂.. 解除sin5°之后,代到上面的式子sin115°=sin5°/2+√3cos5°/2..
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
方正医药连锁NO.12这个地址在什么地方,我要
深圳火车北站属哪区?'
单选题Thenaughtyboytriedtoavoid______.A
美人心计大张嫣是哪集和窦漪房重逢的
根据课文内容填空“洛阳城里见秋风,欲作家书
为什么没有86版聊斋画皮
单选题《人民日报》发表的社论指出:“人民是
丽江古城到洱海怎么走,大理离洱海多少公里,怎
动画电影正义联盟里的那个全身是冰的超级英雄
二年级数学名人名言,关于数学的名人名言!!!
攒机硬件AMD E17010处理器怎么样
下列溶液中Cl-的物质的量浓度最大的是A.200mL
丁一印象地址在什么地方,想过去办事
听说在医院做牵引能让人暂时长高?长高多少?管
篮球内线全套训练方法 急
推荐资讯
电子信息工程专业课自学先学什么啊?
某同学家在住在昆明,暑期去东南亚旅游,他不
内地的中国银行长城卡在澳门取款
想用英语用英语怎么说,“龙虾的钳子”英文怎
1689年,英国议会通过了《权利法案》。这一法
可用于西安城墙的诗句,关于西安的诗词
睾酮1.5能来月经吗
高中语文学习中,为何要一直不断地读古文
求林志炫版本的《花香》《opera》《白天不懂
美到爆的爱情句子,压力压的快窒息了的诗句
能不能办长期护照
力诺瑞特太阳能(缙云县林业局五云野生动物保
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?