黑马程序员技术交流社区

标题: 关于java算术小问题,帮忙看下 [打印本页]

作者: 波涛    时间: 2014-5-17 13:29
标题: 关于java算术小问题,帮忙看下
本帖最后由 波涛 于 2014-5-18 12:24 编辑
  1. public class MathTest{
  2.         public static void main(String[]args){
  3.           double a = 0.01, b = 0.09;
  4.                 System.out.print(a+b);
  5.         }
  6. }
复制代码


打印的结果为什么是0.09999999999999999而非0.1呢?
我想知道为什么以及double最终是怎么个运算法则?我想精确计算怎么办?
作者: chang清    时间: 2014-5-17 13:57
...居然纠结这个。隐约记得是为虚拟机在不同的机器上计算精度的问题,虚拟机的设计者允许结果扩展精度。解决办法,加上一个strictfp在方法前面就可以。
如: public strictf static void main(String[] args){
               //代码
       }
作者: chang清    时间: 2014-5-17 13:58
我晕,上面打错一个字了 。
strictfp
作者: 流沙    时间: 2014-5-17 13:59
哈哈我也菜鸟不知道什么原因,但是1.01加上1.09 就没事
作者: 波涛    时间: 2014-5-17 14:24
chang清 发表于 2014-5-17 13:57
...居然纠结这个。隐约记得是为虚拟机在不同的机器上计算精度的问题,虚拟机的设计者允许结果扩展精度。解 ...

我在main方法前加了strictfp关键字,编译通过了,但运行还是那个结果,没变啊~?大神!
作者: 墨香    时间: 2014-5-17 15:18
浮点数运算会损失精度,因为0.01和0.09转换成二进制时会损失一点小数位,如果你用0.05+0.05就是0.01。0.05转化成二进制不损失精度。建议参考计算机组成原理。
作者: chang清    时间: 2014-5-17 16:12
波涛 发表于 2014-5-17 14:24
我在main方法前加了strictfp关键字,编译通过了,但运行还是那个结果,没变啊~?大神! ...

这个……我没有试过,核心技术上说的是strictfp能得到理想的运算结果。
作者: zy524488    时间: 2014-5-17 16:43
本帖最后由 zy524488 于 2014-5-17 17:05 编辑

其实无论是double还是float都会遇到这个问题,就拿float说话,float的0.1二进制形式是001111011 10011001100110011001101,根据符号位换算为10进制表达的值精确应该是这样计算 110011001100110011001101乘以2的负27次方,实际值是0.100000001490116119384765625
这样就产生了实际误差,
作者: pandapan    时间: 2014-5-17 18:14
论坛中以前有人提过这个问题,不过还是回答一下吧。
java中double 等数据类型精度是个比较恶搞的。在Effective Java中提到,float和double只能用作科学计算或者工程计算,在普通的商业计算,即精算精度要求很高的情况下和计算是否相等的情况下,咱们应该使用的是BigDecimal.使用这个来包装Double对象,这样计算出来的是准确的。使用BigDecimal来就素那加载乘除,算完之后一般使用String输出,另外,如果只是为了单纯的保留几位小数的问题,可以考虑使用DecimalFormat。
希望能够帮到你
作者: 鸭梨的生活    时间: 2014-5-17 18:52
学习。。。。。。。。。。。。。。。。。
作者: 小小6456    时间: 2014-5-17 18:53
学习一下
作者: 小小6456    时间: 2014-5-17 18:54
学习一下咯、、、、、、、、、、、、、、、、、
作者: 张志民    时间: 2014-5-17 19:02
学习了学习了
作者: 肥洋洋    时间: 2014-5-17 21:19
学到了。。。
作者: 蛤蟆太康    时间: 2014-5-17 23:08
还真没注意过这么个小问题,长知识了。
作者: 波涛    时间: 2014-5-18 12:24
组成原理 内伤啊~
作者: stream    时间: 2014-5-18 14:21
肯定是不会等于一的啦。。。。因为这里有精度损失的问题。。。。你了解一下double在计算机里是怎么存储的就知道为什么了。。
作者: chenzhiyuan    时间: 2014-6-3 13:42
学习一下
作者: 不一样的颜色    时间: 2014-6-12 11:23
http://zhaow-381002134.iteye.com/blog/420369看看这里
作者: 依然阿邦    时间: 2014-6-12 11:38
第一次知道还有这个问题,受教了
作者: a6511631    时间: 2014-6-24 09:35
zy524488 发表于 2014-5-17 16:43
其实无论是double还是float都会遇到这个问题,就拿float说话,float的0.1二进制形式是001111011 1001100110 ...

那该实际中如何避免
作者: 钟翠翠    时间: 2014-6-26 13:21
受教了、、、可是真正的解决方法是什么呢?

作者: 钟翠翠    时间: 2014-6-26 13:50
System.out.printf("%.2f%n",(double)0.01+ (double)0.09); 转换成2进制相加
作者: luheqi    时间: 2014-6-26 13:55
不变就对了,0.1无法精确的用二进制表示,所以for循环很忌讳用浮点数来确定两边是否相等的。你试试BigInteger 或者BigDecimal 类,BigDecimal 实现了任意精度的浮点数运算。
作者: bigworld    时间: 2014-6-26 13:57
因为浮点数运算会损失精度
作者: wenzhilanyu    时间: 2014-7-22 11:31
学习了。。。。。。。。。。。。。。。。。。。。。。。
作者: 玉冰竹    时间: 2014-7-24 22:34
同样第一次看到这样的错误 , 学习了!
作者: ssy1939    时间: 2014-8-7 14:06
同意8楼的说法
作者: ﹑淼    时间: 2014-8-8 23:52
double在计算机中是不精确的数。所以运算的结果是一个近似数
作者: 何艳梅    时间: 2014-8-20 11:50
float a = (float)0.01, b = (float)0.09;这样就可以了。
作者: 轩辕苍穹    时间: 2014-8-20 21:06
学习学习!
作者: GYSWL    时间: 2014-8-25 17:38
居然的这样的,得好好学习学习了
作者: 淡淡的雨    时间: 2014-8-26 18:20
细节问题,受教了
作者: 杜工    时间: 2014-9-19 12:03
这是个经典的问题。。。。

作者: Hosing    时间: 2014-11-20 19:25
杜工 发表于 2014-9-19 12:03
这是个经典的问题。。。。

能解释一下吗?
作者: 大鹏鸟    时间: 2014-11-27 23:22
还有这种情况啊?
作者: dimost    时间: 2014-12-22 00:03
学习中!下来试试
作者: lby369    时间: 2014-12-23 21:27
这个问题我也见过。。
作者: dimost    时间: 2014-12-25 23:01
来看看  一楼讲的很精辟
作者: 羽飞翔    时间: 2015-3-14 19:58
还没遇到过这个问题,,提前看看了,嘿嘿
作者: 陈文超    时间: 2015-4-23 22:12
受教了,还没仔细考虑过这个问题
作者: 跃动    时间: 2015-5-14 09:42
zy524488 发表于 2014-5-17 16:43
其实无论是double还是float都会遇到这个问题,就拿float说话,float的0.1二进制形式是001111011 1001100110 ...

        public static void main(String[] args)
        {
                /*double a = 0.01;
                double b = 0.09;
                System.out.println((float)(a+b));*/
               
                float a = 0.01f;
                float b = 0.09f;
                System.out.println((a+b));
        }
输出结果是0.1呀
作者: 严晗哲    时间: 2015-5-31 19:45
学习了好利好
作者: zhubingg    时间: 2015-6-2 22:14
长知识了 .,我都没注意到这个
作者: 1352107393    时间: 2015-6-3 00:22
受教,还是不太懂,去百度问问!!
作者: 陈cc    时间: 2015-8-15 20:48
好犀利的样子!
作者: xlqx15    时间: 2015-8-17 00:30
学习了,又涨姿势了
作者: 不安静的丑男子    时间: 2015-8-26 22:53
长知识了 .,我都没注意到这个
作者: 灵韵依存    时间: 2015-11-21 13:44
学习中  




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