我们先来看一个题目:求一维数组double rea[10]中所有元素的整数部分和小数部分之和。题目也不难,先看下答案:
代码语言:javascript复制#include "stdio.h"
int main()
{
double rea[10]={ 8.95,68.81,43.21,13.55,69.38,56.46,15.52,76.06,82.33,83.17 };
int sum1;
double sum2;
/***********begin***********/
int i;
for( sum2=0,i=0,sum1=0 ; i<10 ; i )
{
sum1 = sum1 (int)rea[i];
sum2 = sum2 rea[i]-(int)rea[i]; //小数部分
}
/************end************/
printf("sum1=%d,sum2=%.2fn",sum1,sum2);
return 0;
}
方法有很多,我们这里三分别取整数部分、小数部分,通过循环累计求和加起来。看下运行结果:
但有同学在求每个元素小数部分用了其他方法,看似正确的步骤得到的结果却不一样。
代码语言:javascript复制sum2 = sum2 (int)(rea[i]*100)0/100.0; //小数部分
也是很有想法,虽然复杂了点,但计算之后确实应该是取小数部分,看起来没有问题。但运行结果却变成下面这样了:
差了0.01 。问题出在什么地方呢?我们先看下下面这行代码运行结果:
代码语言:javascript复制printf("%dn",(int)(8.95*100));
8.95*100 结果居然不是895 ?原因是8.95*100结果可能是894.999,取整就变成了894 。
我们知道计算机里面数值都是用2进制表示的,会存在有些数值无法准确表示的问题。就像10进制,不管保留多少位小数都不能精确的表示1/3一样。
再看一个例子:
代码语言:javascript复制#include <stdio.h>
int main()
{
float a;
scanf("%f", &a);
printf("%fn",a);
return 0;
}
运行结果:
569.261
569.260986
我们输入的数值是569.261,实际保存的却是569.260986。因为float只有4个字节表示,精度更低。我们在数值处理的时候,步骤要尽可能简单,越是复杂,问题越多;尽量使用double类型,少用float;对于精度有特殊要求的要注意想其他办法解决。