A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马刘杰 中级黑马   /  2013-2-25 14:49  /  2246 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 黑马刘杰 于 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的运算得到的结果永远都是近似值?我该如何计算象这样的数值呢?

评分

参与人数 2技术分 +1 黑马币 +9 收起 理由
高境 + 1 神马都是浮云
Rancho_Gump + 9

查看全部评分

6 个回复

倒序浏览
本帖最后由 王昕 于 2013-2-25 15:02 编辑

因为很多十进制的小数用二进制表示都只能是近似值,就像十进制表示1/3是近似值0.3循环一样,double只是用来进行一些科学计算和工程计算,那样的话精确度一般足够了,不用来做条件分支,循环的条件什么的。要是想精确的计算,要用java.math.BigDecimal。
回复 使用道具 举报
  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了
回复 使用道具 举报
其实最保险的方法还是使用进制,因为进制数值是固定的。
回复 使用道具 举报
这段代码我是不等呢,你可以转换一下就知道,下面是我转换的结果,你看看:
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

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1

查看全部评分

回复 使用道具 举报
对了,对于这种float和double类型的运算,没有什么现成的公式可以解决,因此尽量不要使用它们。当然了,在某些对计算结果要求不高的应用中, 可以使用它们
回复 使用道具 举报
王宝生 发表于 2013-2-26 09:04
对了,对于这种float和double类型的运算,没有什么现成的公式可以解决,因此尽量不要使用它们。当然了,在 ...

嗯,谢谢啊
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马