您的位置:首页 > 其它

关于float相减精度丢失的问题

2014-07-16 15:11 615 查看
做项目的时候用到float相减发现结果小数点后面居然有一串小数,上网找了找资料发现了原因:

小数的二进制表示问题

首先我们要搞清楚下面两个问题:

(1) 十进制整数如何转化为二进制数

算法很简单。举个例子,11表示成二进制数:

11/2=5 余 1

5/2=2 余 1

2/2=1 余 0

1/2=0 余 1

0结束 11二进制表示为(从下往上):1011

这里提一点:只要遇到除以后的结果为0了就结束了,大家想一想,所有的整数除以2是不是一定能够最终得到0。换句话说,所有的整数转变为二进制数的算法会不会无限循环下去呢?绝对不会,整数永远可以用二进制精确表示 ,但小数就不一定了。

(2) 十进制小数如何转化为二进制数

算法是乘以2直到没有了小数为止。举个例子,0.9表示成二进制数

0.9*2=1.8 取整数部分 1

0.8(1.8的小数部分)*2=1.6 取整数部分 1

0.6*2=1.2 取整数部分 1

0.2*2=0.4 取整数部分 0

0.4*2=0.8 取整数部分 0

0.8*2=1.6 取整数部分 1

0.6*2=1.2 取整数部分 0

......... 0.9二进制表示为(从上往下): 1100100100100......

注意:上面的计算过程循环了,也就是说*2永远不可能消灭小数部分,这样算法将无限下去。很显然,小数的二进制表示有时是不可能精确的 。其实道理很简单,十进制系统中能不能准确表示出1/3呢?同样二进制系统也无法准确表示1/10。这也就解释了为什么浮点型减法出现了"减不尽"的精度丢失问题。

解决办法:
BigDecimal
b1 = new BigDecimal(Float.toString(xx));

BigDecimal b2 = new BigDecimal(Float.toString(yy));

float ss = b1.subtract(b2).floatValue();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: