|
因为float经常能给你一些惊喜
例如论坛上常常看到的
- #include <stdio.h>
- #include <stdlib.h>
- int main()
- {
- float a, b, c;
- a = 5.2;
- b = 3.1;
- c = a+b;
- printf("%f\n", c);
- system("pause");
- return 0;
- }
复制代码
输出是8.299999,这明显不正确
有人会教你这么做
输出是变成8.3了,但是%.1f是什么?
是进行近似处理,保留一位小数
所以说,%.1f对于解决这个问题根本没有帮助,输出的是近似后的结果,如果需要精确结果呢?
如何让计算机给出精确的结果才是我们想要的,而不是一个看上去正常的结果
这里的原因在于,二进制小数和我们熟悉的十进制小数有很大的不同。
一个最简分数,如果分母进行质因数分解后仅含2和5,那么这个分数就能写成有限小数(因为10的质因子是2和5)
但是对于二进制小数来说,规则就变了。很多有限小数转换成二进制,是没办法写成有限小数的,上面的8.3就是这么一个例子。
没法写成有限小数,就只能写出一部分小数位来近似了(例如把1/3近似成0.333333)
所以说,二进制小数是注定不精确的。
float呢,特别不精确,它只能保证6位的有效数字。(注意,是有效数字,不是小数点后位数。1000.001有7位有效数字,0.001有1位有效数字,定义可以自己去查,想必自己动手查要比在这里转述一句效果好)
特别在整数位上有数字的时候,用float的结果就是灾难性的:
- #include <stdio.h>
- #include <stdlib.h>
- int main()
- {
- float a, b, c;
- a = 50000000.2;
- b = 3.1;
- c = a+b;
- printf("%f\n", c);
- system("pause");
- return 0;
- }
复制代码
输出是50000004.000000,0.7就这样被吃掉了。
可能会有人觉得0.7相对于整个数字来说微不足道,但是如果是银行的结算程序,银行是肯定不愿意亏这7毛钱的。
为什么会这样呢?重复前面的一句话,float仅有6位有效数字,从左边开始数6个数字,确实是正确的。
看到这里你可能就会明白了,float是一种”没用的东西“(引号去掉大体上也是可以的) |
|