黑马程序员技术交流社区

标题: 浮点数的不精准问题求解 [打印本页]

作者: cat73    时间: 2016-1-9 21:38
标题: 浮点数的不精准问题求解
本帖最后由 cat73 于 2016-1-9 21:48 编辑

有如下 Java 代码,其输出结果已经在后面以注释的形式给出↓
  1. double a = 0.2d;
  2. double b = 0.4d;
  3. double n = a + b;
  4. double n2 = 0.6d;

  5. System.out.println(a); //  0.2
  6. System.out.println(b); //  0.4
  7. System.out.println(n); //  0.6000000000000001
  8. System.out.println(n2); // 0.6
复制代码

在 JavaScript、Python3 中可以得出相同的结果。
那么问题来了,为什么会出现这样的结果呢?

=============================

现在再打开你电脑上自带的计算器试试,0.2 + 0.4 = 0.6!
为何计算器可以得出正确的结果呢?
我们又要如何才能在编程中得到正确的结果呢?

作者: OliverLC    时间: 2016-1-10 01:18
变成字符串对象再操作就Ok.至于为啥,我也不晓得...
作者: 好好搬砖    时间: 2016-1-10 16:00
本帖最后由 好好搬砖 于 2016-1-11 16:24 编辑

###14.15_常见对象(BigDecimal类的概述和方法使用)
* A:BigDecimal的概述
        * 由于在运算的时候,float类型和double很容易丢失精度,演示案例。
        * 所以,为了能精确的表示、计算浮点数,Java提供了BigDecimal
        * 不可变的、任意精度的有符号十进制数。
* B:构造方法
        * public BigDecimal(String val)
* C:成员方法
        * public BigDecimal add(BigDecimal augend)
        * public BigDecimal subtract(BigDecimal subtrahend)
        * public BigDecimal multiply(BigDecimal multiplicand)
        * public BigDecimal divide(BigDecimal divisor)
* D:案例演示
        * BigDecimal类的构造方法和成员方法使用
-------------------------------为何会出现不精准的问题,参考知乎的回答---------------------------------
https://www.zhihu.com/question/28551135

M{ (132.27 KB, 下载次数: 17)

M{

作者: 1379号监听员    时间: 2016-1-10 17:52
BigDecimal 对象就是为你这个问题量身定做的啊骚年!!!
作者: cat73    时间: 2016-1-10 22:32
好好搬砖 发表于 2016-1-10 16:00
###14.15_常见对象(BigDecimal类的概述和方法使用)
* A:BigDecimal的概述
        * 由于在运算的时候,float类型 ...

那么现在就解决了其中一个问题:如何避免计算时出现不精准的问题。
但是还是没有搞清楚,为何会出现不精准的问题。
我们已经知道 0.2、0.4、0.6 都可以精准的用 double 表示出来。
也就是说 0.2 + 0.4 的结果 0.6 是可以被 double 表示出来的。
那为何实际计算的结果为 0.6000000000000001 呢?
作者: 姚成晖    时间: 2016-1-10 22:36
直接运算底层用的是2进制补码运算的,  

BigDecimal完美解决
作者: 放养的饼干    时间: 2016-1-10 22:49
BigDecimal就是解决的方法,至于原因:类似于10进制中标识1/3一样,你只能得到0.333333333...却永远无法精确,二进制中也有一些无限循环的小数无法精确表示,所以就造成了你代码中的结果
作者: 放养的饼干    时间: 2016-1-10 22:50
就想你用double表示10,他就是10.0,但你用double表示个10/3试试,3.33333333333333333333....
作者: fengfeng520    时间: 2016-1-10 23:40
感觉都好厉害啊  
作者: 好好搬砖    时间: 2016-1-11 16:26
cat73 发表于 2016-1-10 22:32
那么现在就解决了其中一个问题:如何避免计算时出现不精准的问题。
但是还是没有搞清楚,为何会出现不精 ...

为何会出现不精准的问题?参考知乎的回答。
https://www.zhihu.com/question/28551135
作者: 放养的饼干    时间: 2016-1-12 23:35
我是坏人, 发表于 2016-1-10 22:36
直接运算底层用的是2进制补码运算的,  

BigDecimal完美解决

确实我也不太清楚到底是为什么,不过建议你想知道的话去看看IEEE754,这个是浮点数储存的标准。
应该是与浮点数在内存中储存的方式有关系,我是没看太懂




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2