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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 晏文根 初级黑马   /  2012-6-14 14:13  /  2099 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

记得一个偶然的机会计算0.05+0.01输出的结果是:0.06000000000000005
后来又写了个代码运行下,发现结果真的不对。于是就百度了一下,发现java中确实存在精度不准的问题。还有一些例子,但没有解释其原因和修正方法。
public class Demo
{
   public static void main(String[] args)
   {
      System.out.println(0.05+0.01);
      System.out.println(1.0-0.42);
      System.out.println(4.015*100);
      System.out.println(123.3/100);
   }
}
我的运行结果是:0.0600000000000005
             0.58000000000000001
             401.4999999999999994
             10232999999999999999
如果你的结果是对的,就多运行几次,我感觉结果错的概率好大呀!
请高手们指教,最好把原因和修正方法都说下,谢谢!

7 个回复

倒序浏览
告诉你吧 实型数据在内存中是近似存储的,你这个让我想到了以前的一道题
  1. class Demo2
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 //System.out.println("Hello World!");
  6.                 double a=2.0,b=1.1,c=0.9;
  7.                 System.out.println(a-b==c?true:false);
  8.         }
  9. }
复制代码
上面代码打印的是false,希望能帮助你理解一下!
回复 使用道具 举报
原因如下:
1.十进制的二进制表示有可能不正确,浮点数由两部分组成:指数和尾数,浮点数的值实际上是由一个特定的数学公式计算得到的,由于指数和尾数的位数有限,那么必然有精确度损失。
2.当两个十进制进行计算的时候,首先在底层应该对阶,然后进行计算,这很有可能引起精确度损失。
3.而你直接输出一个十进制数而不进行计算的时候,精确度损失的概率就比较小了。
回复 使用道具 举报
浮点运算很少是精确的,只要是超过精度能表示的范围就会产生误差。往往产生误差不是因为数的大小,而是因为数的精度。在使用 float 和 double 作精确运算的时候要特别小心。
可以考虑采用一些替代方案来实现。如通过 String 结合 BigDecimal 或者通过使用 long 类型来转换。
回复 使用道具 举报
我修改了一下,写了
public class Demo
{
   public static void main(String[] args)
   {
      for (int x=1; x<5000;x++ )
      {
                  if ((0.05+0.01)==0.06)
                  {
                          System.out.println("对了");
                  }
      }
        for (int x=1; x<5000;x++ )
        {
                if ((1.0-0.42)==0.58)
                {
                  System.out.println("对了");
                }
        }
        for (int x=1; x<5000;x++ )
        {
                if ((4.015*100)==401.5)
                {
                  System.out.println("对了");
                }
        }
        for (int x=1; x<5000;x++ )
        {
                if ((123.3/100)==1.233)
                {
                  System.out.println("对了");
                }
        }
   }
}

结果什么都没打印。
回复 使用道具 举报
孟浩然 发表于 2012-6-14 14:32
告诉你吧 实型数据在内存中是近似存储的,你这个让我想到了以前的一道题上面代码打印的是false,希望能帮助 ...

请问你怎么写成了这样带格式的代码?谢谢
回复 使用道具 举报
胡卿 中级黑马 2012-6-14 14:46:07
7#
Java中的简单浮点数类型float和double不能够进行运算
回复 使用道具 举报
张頔 中级黑马 2012-6-14 16:52:44
8#
解决方法,将double类型的数转化为float,至于深层次的原因不是很了解,只知道关于浮点的运算都转化成float就行。
System.out.println((float)(0.05+0.01));
System.out.println((float)(1.0-0.42));
System.out.println((float)4.015*100);
System.out.println((float)123.3/100);


结果:
0.06
0.58
401.5
1.233
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马