黑马程序员技术交流社区

标题: double类型的运算错误 [打印本页]

作者: 黑马刘杰    时间: 2013-2-25 14:49
标题: double类型的运算错误
本帖最后由 黑马刘杰 于 2013-2-26 13:19 编辑
  1. private static void foo1() {
  2.                 //下面代码为什么输出是NO?
  3.                 double x = 2.0, y = 1.1, z = 0.9;
  4.                 if (x - y == z) {
  5.                         System.out.println("YES!");
  6.                 } else {
  7.                         System.out.println("NO!");
  8.                 }
  9.         }
复制代码
网上说是内部存储的问题。但是像这种2.0-1.1的运算得到的结果永远都是近似值?我该如何计算象这样的数值呢?

作者: 王昕    时间: 2013-2-25 14:58
本帖最后由 王昕 于 2013-2-25 15:02 编辑

因为很多十进制的小数用二进制表示都只能是近似值,就像十进制表示1/3是近似值0.3循环一样,double只是用来进行一些科学计算和工程计算,那样的话精确度一般足够了,不用来做条件分支,循环的条件什么的。要是想精确的计算,要用java.math.BigDecimal。
作者: 黄玉昆    时间: 2013-2-25 15:09
  1. private static void foo1()
  2.         {
  3.                 //下面代码为什么输出是NO?
  4.                 System.out.println(m);
  5.                 if ((x-y)*10/10 == z) {
  6.                                 System.out.println("YES!");
  7.                 } else {
  8.                                 System.out.println("NO!");
  9.                 }
  10.         }
复制代码
你试试这样可以不可以。输出应该为yes了
作者: 黄玉昆    时间: 2013-2-25 15:09
其实最保险的方法还是使用进制,因为进制数值是固定的。
作者: 王宝生    时间: 2013-2-26 09:01
这段代码我是不等呢,你可以转换一下就知道,下面是我转换的结果,你看看:
x=2.0在机器中存储的是2.0000 0000 0000 0000
y=1.1在机器中存储的是1.1000 0000 0000 0001 哈哈你看看,这里已经不是1.1了
z=0.9在机器中存储的是0.9000 0000 0000 00009 这里是不是也已经不是0.9了

然后x-y不是等于0.9而是等于0.8999 9999 9999 9999 1
现在你明白为什么不等咯吧!
不过仔细观察这段数字,你可以这样修改,将所有double类型改了float就能正确工作,不过这是治标不治本。

就像上面所说的,float和double一般都用在工程计算中,而不是用在金融计算中,你可以参考下面这篇文章,我感觉不错的
http://wenku.baidu.com/view/2f9bfd691eb91a37f1115cda.html
作者: 王宝生    时间: 2013-2-26 09:04
对了,对于这种float和double类型的运算,没有什么现成的公式可以解决,因此尽量不要使用它们。当然了,在某些对计算结果要求不高的应用中, 可以使用它们
作者: 黑马刘杰    时间: 2013-2-26 09:05
王宝生 发表于 2013-2-26 09:04
对了,对于这种float和double类型的运算,没有什么现成的公式可以解决,因此尽量不要使用它们。当然了,在 ...

嗯,谢谢啊




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