浮点数精度丢失
先来看一下下面一段简单的代码:
按理说a-b不是应该等于0.01吗,但运行结果确实0.010000000000000009。那么为什么会有差别呢?这个差别到底打不打呢?
再来看下面一段代码:
显然,结果是不等于0.01。
这就是使用double会产生精度丢失,可能会产生一些bug。
但是所有的浮点数都会有精度丢失吗?
来看下面的代码:
输出结果是0.3 - 0.15 = 0.15,double类型的0.3和0.15的运算没有出现精度丢失。
首先在计算机中一个整数是以二进制01010来表示的,浮点数也不例外。
例:
7除以2等于3余1
13除以2等于6余1
所以7的二进制表示为:111
0.99 * 2 = 1 + 0.98 --> 1
0.98 * 2 = 1 + 0.96 --> 1
这样周而复始的话是没有尽头的,double的有效数字有限,所以必定会有丢失,二进制无法准确表达0.99,十进制也无法准确的表达1/3。
float和double类型使用不当也会出现精度丢失问题。
例:
float和double类型的结构包括符号位、指数位和尾数位。
精度(有效数字)主要看尾数位:
float的尾数位是23位,对应7~8位十进制数,所以有效数字有的编译器是7位,也有的是8位;
double的尾数位是52位,对应15~16位十进制数,有效数字位15位或16位。
解决方法
在需要精确的表示两位小数时我们需要把他们转换为BigDecimal对象,然后再进行运算。BigDecimal实现了任意精度的浮点数运算。