黑马程序员技术交流社区

标题: 关于float类型计算误差的问题 [打印本页]

作者: 王永旺    时间: 2012-4-16 23:33
标题: 关于float类型计算误差的问题
刚做一个小测试,偶然发现float类型的数据进行相加会产生很大误差,
例如:
public class Demo{
        public static void main(String[] args){
                float f1 = 8.1f;
                float f2 = 2.6f;
                System.out.println(f1+f2);
        }
}

得出的结果是10.700001,有谁知道这个误差是怎么产生的,误差有固定数值么。
作者: 王怡然    时间: 2012-4-16 23:51
这个你去看一下java中print的函数源代码里看一下,是因为里面有个toJavaFormatString()的缘故,它会在将float变量转换为String类型时做一个精度的这个知道就行,以后不要犯这样的错误就行...
作者: 曾虓    时间: 2012-4-17 01:25
本帖最后由 曾虓 于 2012-4-17 01:33 编辑

浮点数直接运算有可能会丢失精度的。
因为十进制数的二进制表示可能不够精确浮点数或是双精度浮点数无法精确表示的情况并不少见。浮点数值没办法用十进制来精确表示的原因要归咎于CPU表示浮点数的方法。这样的话您就可能会牺牲一些精度,有些浮点数运算也会引入误差。比如,2.4的二进制表示并非就是精确的2.4。反而最为接近的二进制表示是 2.3999999999999999。原因在于浮点数由两部分组成:指数和尾数。浮点数的值实际上是由一个特定的数学公式计算得到的。您所遇到的精度损失会在任何操作系统和编程环境中遇到。
类型失配
您可能混合了浮点数和双精度浮点数类型。请确定您在进行数学运算的时候所有的数据类型全部相同。
注意:float类型的变量只有7位的精度,而double类型的变量有15位的精度。
如何进行浮点数精度计算?
在《Effective Java》这本书中也提到:float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal。

所以楼主的代码改成这样:
  1. import java.math.BigDecimal;

  2. public class Test {
  3.         public static void main(String[] args) {
  4.                 float f1 = 8.1f;
  5.                 float f2 = 2.6f;
  6.                 BigDecimal b1 = new BigDecimal(Float.toString(f1));
  7.                 BigDecimal b2 = new BigDecimal(Float.toString(f2));
  8.                 System.out.println(f1 + f2);
  9.                 System.out.println(b1.add(b2).floatValue());
  10.         }
  11. }
复制代码
结果如图:



作者: 关天笑    时间: 2012-4-17 01:50
曾虓 发表于 2012-4-17 01:25
浮点数直接运算有可能会丢失精度的。
因为十进制数的二进制表示可能不够精确浮点数或是双精度浮点数无法精 ...

这个回复的最详细准确




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