关于Java中2.0-1.1!=0.9的问题

关于Java中2.0-1.1!=0.9的问题

问题引出:

在《Java核心技术》中关于浮点数值计算部分提到,System.out.println(2.0-1.1)这条语句并不是想当然的0.9,而是0.8999999999999999,倒也不是很惊讶,我知道大概的原因是:浮点数值用二进制的形式来表现,从而造成了一部分位数丢失。但是,具体细节我其实并不知道,所以花了一些时间,翻阅了一些前辈大牛写的文章,有了一定的认识,特此记录以下。

我还做了以下尝试:

System.out.println(0.01f+0.04f);//输出0.049999997
System.out.println(0.01f+0.04);//输出0.04999999977648258
System.out.println(2.0-1.1);//输出0.8999999999999999
System.out.println(2.0f-1.1f);//输出0.9
System.out.println(2.0-0.1);//输出1.9

一些总结:

  • 整数和小数转换成二进制数,机制不同。整数除二取余,直到为1为之,一定不会无限循环,所以能够精确用二进制表示。但小数不同,小数部分乘以2,取整数部分,再把小数部分乘以2...直到小数部分为0为止,是有一定几率无限循环下去的。
  • Java中会将未声明类型的小数默认当做double型处理,也就是语句3的情况。而语句4声明数值类型为float时,因为本身存在精度上的丢失,反而输出了0.9。
  • 语句1和语句2输出差异在于0.01f在精度上的差异,具体可以参考链接:[解惑]剖析float型的内存存储和精度丢失问题
  • 那么语句5同样是两个double类型相加,为什么输出又是“正确”的呢,参考:为什么在java中 2.0-1.1=0.899999... 但是2.0-0.1却可以=1.9?中的回答。

猜你喜欢

转载自www.cnblogs.com/summerday152/p/11842680.html