0.8999999999999999
我想一般正常的人类都会计算出2.0-1.1=0.9这个答案,因此计算机给出的这个答案就显得有些奇怪。而当我们执行以下代码的时候,控制台输出的结果又是0.9了。
float f1=2.0f; float f2=1.1f; System.out.println(f1-f2);
我觉得很奇怪,很不理解= =于是去找答案。结论如下:
1.在Java中,未声明类型的小数会被默认当做double型处理。
2.浮点数在计算机中的存储是二进制,具体请看:http://hxraid.iteye.com/blog/504293
写的通俗易懂,非常值得一看,而且很好的解释了为什么是0.8999999999999999
3.将double型数据转换为float型数据时,会有一定程度上的精度丢失,因此用float做2.0-1.1的时候,反而得到了“准确”的答案。
按理来说事情到此就应该结束了,但是我不知道抽哪门子的风= =用C语言也做了一下这个测试:
printf("%f",2.0-1.1);
输出结果为:0.900000 当时我很没形象的狂喊“这不科学”,于是有了以下内容。
1.C语言中处理未声明的小数,跟Java同样是默认按照double型来处理的。
2.C语言中对小数的存储遵循的跟Java是同一套标准。
3.根据“默认参数提升”原则,在printf()中,%f代表的是double型数据,就算后面的值是float也会被提升为double型。
既然是这样,那么为毛会输出0.900000呢?
因为在printf()中,%f占位符在未设置小数位长度的状态下,默认输出6位,而6位显然是没法把一个double型数据“完整”输出的,因此计算机做了一定程度上的取舍,然后输出了0.9。
printf("%.30f",2.0-1.1);
如果执行这条语句,就可以看到跟Java相类似的结果。
最后贴一个链接,是讲解C++中cout方法如何控制小数位的,个人觉得还是会用得上的:
http://www.chineselinuxuniversity.net/articles/40380.shtml
至此,全部问题解决。