c语言初学,求解

求一个表达式的值。表达式由两个非负整数x,y和一个运算符op构成。这两个整数和运算符的顺序是随机的,可能是”x op y”, “op x y”或者 “x y op”。x和y均不大于10000000,op可以是+,-,*,/,%中的任意一种,分表表示加法,减法,乘法,除法和求余。如输入 5 20 * ,输出100
(现在不清楚这个随机顺序输入该怎么搞)

一般用gets读入一行,再用字符串处理为s1、s2、s3三个字符串,或者scanf("%s%s%s", s1,s2,s3)直接读入;

然后第一步是找出op,测试两次:

如果 s1 åœ¨ â€œ+-*/”中,那么 op=s1;x=s2;y=s3;
如果 s2 åœ¨ â€œ+-*/”中,那么 op=s2;x=s1;y=s3;
否则 op=s3;x=s1;y=s2;

接下来你会处理了吧,switch(op[0]) 输出x +(或者-*/) y的结果

温馨提示:答案为网友推荐,仅供参考
第1个回答  2018-01-20

这是由于浮点数误差导致的。其根本原因是计算机所使用二进制01代码无法准确表示某些带小数位的十进制数据。我们知道将一个十进制数值转换为二进制数值,需要通过下面的计算方法:
1. 整数部分:连续用该整数除以2,取余数,然后商再除以2,直到商等于0为止。然后把得到的各个余数按相反的顺序排列。简称"除2取余法"。
2. 小数部分:十进制小数转换为二进制小数,采用"乘2取整,顺序排列"法。用2乘以十进制小数,将得到的整数部分取出,再用2乘余下的小数部分,然后再将积的整数部分取出,如此进行,直到积中的小数部分为0或者达到所要求的精度为止。然后把取出的整数部分按顺序排列起来,即先取出的整数部分作为二进制小数的高位,后取出的整数部分作为低位有效位。简称"乘2取整法"。
3. 含有小数的十进制数转换成二进制,整数、小数部分分别进行转换,然后相加。

这导致了一个显而易见的问题:有些十进制数无法转换为有限的二进制数:

(0.65)10 = (0.101001100110011001100110011001100110011......)2
(0.6) 10 = (0.10011001100110011001100110011001100110011......)2

后面的省略号表示已经算不完了,后面在无限重复 0011 这段二进制数值

目前计算机上存储浮点数值是按照IEEE(电气和电子工程师协会)754浮点存储格式标准来存储的。
IEEE单精度浮点格式共32位,包含三个构成字段:23位小数f,8位偏置指数e,1位符号s。将这些字段连续存放在一个32位字里,并对其进行编码。其中0:22位包含23位的小数f; 23:30位包含8位指数e;第31位包含符号s。如下图所示:

也就是说上面将0.65及0.5转换出的二进制代码,我们只能存储23位,即使数据类型为double,也只能存储52位,这样大家便能看出问题出现的原因了。

可惜的的是我们无法从根本上解决问题,除非你能发明十进制计算机,但我们可以曲线救国:

    因为二进制数值可以准确表示整数(可以使用整数转换为二进制方法验证下),所以可以将小数乘以10或100等变成整数,然后做整数运算,最后再通过除以10或100等获得结果;
    2. 通过截取结果的有效小数位数等,来取得最好的近似结果,然后在做处理。
    3. 对于可以用有限长度的二进制数值表示的十进制数值,可以使用存储位数大于其长度的数据类型。

参考CNSD

第2个回答  2017-12-31
#include<stdio.h>

int main()
{
char str[32];
long x,y;

scanf("%s",str);
if(!(str[0]>='0' && str[0]<='9'))
scanf("%ld %ld",&x,&y);
else
{
x=atol(str);
scanf("%s",str);
if(!(str[0]>='0' && str[0]<='9'))
scanf("%ld",&y);
else
{
y=atoi(str);
scanf("%s",str);
}
}
switch(str[0])
{
case '+':
printf("%ld\n",x+y);
break;
case '-':
printf("%ld\n",x-y);
break;
case '*':
printf("%ld\n",x*y);
break;
case '/':
if(0!=y)
printf("%ld\n",x/y);
else
printf("除数不能为0!\n");
break;
default:
printf("非法的运算符%s!\n",str);
break;
}
return 0;
}
相似回答