浮点数精度缺失

由于数据表示精度问题,浮点数应慎用“==”比较相等,且浮点数的结合律有时不成立。例如:

  1. System.out.println((0.1+ 0.2) + 0.3);                                   //输出0.6000000000000001
    System.out.println(0.1 + (0.2 +0.3));                                  //输出0.6
    System.out.println((0.1+ (0.2 + 0.3)) == ((0.1 + 0.2) + 0.3));   //输出false
  2. 此处的0.3无法用二进制数精确表示,而0.5能用二进制数精确表示.

 

1.十进制小数如何转化为二进制数?
算法是乘以2直到没有了小数为止。举个例子,0.3表示成二进制数

                    0.3*2=0.6   取整数部分  0

                    0.6*2=1.2   取整数部分  1

                    0.2(1.2的小数部分)*2=0.4   取整数部分 0

                    0.4*2=0.8   取整数部分  0

                    0.8*2=1.6    取整数部分 1

                 0.6*2=1.2   取整数部分  1

                             .........     0.3二进制表示为(从上往下):0100110011...... 

          注意:上面的计算过程循环了,也就是说*2永远不可能消灭小数部分,这样算法将无限下去。很显然,小数的二进制表示有时是不可能精确的 而0.5能用二进制数精确表示0.5*2=1.0时能取整数部分其实道理很简单,十进制系统中能不能准确表示出1/3呢?同样二进制系统也无法准确表示1/10。这也就解释了为什么浮点型减法出现了"减不尽"的精度丢失问题。

参考自:
http://hxraid.iteye.com/blog/504293

2.float类型的存储

float类型的二进制存储是4个字节32位

1位符号位   8位阶码位 23位尾数位


(1)将十进制0.5转换为整数部分和小数部分的二进制 0.1

(2)转换为 1.0*2的-1次方

(3)符号位为0

(4)阶码位,e-127=-1,e=126,转换为二进制为01111110

(5)小数位,0

(6)40.125f的二进制表现形式为0011111100000000 00000000 00000000

float a=0.5f;

intb=Float.floatToIntBits(a);//Float类的静态方法,以int类型的方式返回这个小数的二进制形式

System.out.println(Integer.toBinaryString(b));

3.总结


       由于浮点数一旦超过精度,就会产生误差,而且可能与数的大小无关。故在浮点数比较

与精确度要求较高的情况下,应使用BigDecimal。

 

 

 


你可能感兴趣的:(浮点数,精度缺失)